getnstimeofdayは、__ get_realtime_clock_tsのフロントエンドですが、システムで使用可能な高解像度クロックがない場合にも機能します。 この場合、(kernel / time / timekeeping.cの代わりに)kernel / time.cで定義されているgetnstimeofdayを使用して、低解像度の要件のみを満たすtimespecを提供します。
Linuxカーネルは、時間を管理するための多数のインターフェースを提供します。 getnstimeofdayはそれらの1つであり、秒とナノ秒で時間を示します。 この関数は「timekeeping32.h」に実装されており、2つのメンバーを持つtimespec型の構造体を返します。
struct timespec64 { time64_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ };
時刻を出力するには、関数getnstimeofdayの呼び出しによって埋められるtv_secとtv_nsecの値を出力するだけで済みます。 次のサンプルコードでは、gettimeというprocエントリを作成しました。これは、読み取られたときに秒とナノ秒の値を出力します。
#include <linux/module.h> #include <linux/kernel.h> #include <linux/proc_fs.h> #include <linux/slab.h> int len; char *msg; ssize_t size; struct timespec ts; ssize_t read_proc(struct file *filp,char *buf,size_t count,loff_t *offp ) { struct timespec ts; char *temp; temp=kmalloc(50*sizeof(char),GFP_KERNEL); getnstimeofday(&ts); sprintf(temp,"%ld seconds n%ld nanosecondsn",ts.tv_sec, ts.tv_nsec); len=strlen(temp); size=sizeof(char)*len; return simple_read_from_buffer(buf,count,offp,temp,size); } struct file_operations proc_fops = { read: read_proc }; void create_new_proc_entry(void) { proc_create("gettime",0,NULL,&proc_fops); } int proc_init (void) { create_new_proc_entry(); return 0; } void proc_cleanup(void) { remove_proc_entry("gettime",NULL); } MODULE_LICENSE("GPL"); module_init(proc_init); module_exit(proc_cleanup);
上記のコードをproc_read_gettimeofday.cとして保存し、次のmakefileを使用してコードをコンパイルします。
ifneq ($(KERNELRELEASE),) obj-m := proc_read_gettimeofday.o else KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean endif
以下を使用してモジュールをコンパイルおよび挿入します。
$ make $ sudo insmod proc_read_getnstimeofday.ko
出力を確認するには、catコマンドを使用してprocエントリgettimeを読み取ります。
# cat /proc/gettime 1584690328 seconds 290430470 nanoseconds
The post Linuxカーネルでgetnstimeofdayを使用する例–オタク日記 appeared first on Gamingsym Japan.