@dslab
/* How to use:
* #cat /proc/kernel_timer
*/
init:
创建 /proc/kernel_timee入口项
clearup:
删除 init创建的入口项
kernel_timer:
1》分配 k_t_data变量
2》打印出表头
3》设置并添加内核定时器
4》把自己挂到等待队列上,等待LOOPS次读取时间打印时间完毕
5》释放内存变量
6》返回操作数据的字节数
kernel_timer_handler:
内核定时器处理函数
/////具体实现 >>>>>>>> 抄自ldd 所带源码 jit.c
#include <linux/proc_fs.h> #include <linux/timer.h> #include <linux/sched.h> #include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> #include <linux/time.h> #include <linux/timer.h> #include <linux/kernel.h> #include <linux/proc_fs.h> #include <linux/types.h> #include <linux/spinlock.h> #include <linux/interrupt.h> #include <asm/hardirq.h> #define LOOPS 5 //how many lines to print struct k_t_data { struct timer_list timer; unsigned long prejiffies; //previous jiffies value unsigned char* buf;//page address where to write to int loops;// how many lines to print wait_queue_head_t wait;//while printing let our main process //wait on this queue }; int tdelay = 10; void kernel_timer_handler(unsigned long arg) { struct k_t_data* data = (struct k_t_data*) arg; unsigned long jif = jiffies; data->buf += sprintf(data->buf, "%9li %3li %i %6i %i %s/n", jif, jif - data->prejiffies, in_interrupt() ? 1 : 0, current->pid, smp_processor_id(), current->comm); if (--data->loops) { data->timer.expires += tdelay; data->prejiffies = jif; add_timer(&data->timer); } else { wake_up_interruptible(&data->wait); } } int kernel_timer(char *buf, char **start, off_t offset, int len, int *eof, void *unused_data) { struct k_t_data* data; char* write2 = buf; unsigned long jif = jiffies; data = kmalloc(sizeof(struct k_t_data), GFP_KERNEL); if (!data) return -ENOMEM; init_timer(&data->timer); init_waitqueue_head(&data->wait); /* Write the table header to the buffer */ write2 += sprintf(write2, " time delta inirq pid cpu command/n"); write2 += sprintf(write2, "%9li %3li %i %6i %i %s/n", jif, 0L, in_interrupt() ? 1 : 0, current->pid, smp_processor_id(), current->comm); /* fill the data for our timer function */ data->prejiffies = jif; data->buf = write2;// the next position to write to data->loops = LOOPS; // how many times to read and print /* register kernel timer */ data->timer.data = (unsigned long) data; // argument of kernel_timer_handler data->timer.function = kernel_timer_handler; data->timer.expires = jif + tdelay; add_timer(&data->timer); /* wait for the buffer to fill */ wait_event_interruptible(data->wait, !data->loops); if (signal_pending(current)) return -ERESTARTSYS; write2 = data->buf;//The latest position kfree(data); return write2 - buf; } int __init kernel_timer_init(void) { //create "/proc/kernel_timer" entry create_proc_read_entry("kernel_timer", 0, NULL, kernel_timer, NULL); return 0; } void __exit kernel_timer_clearup(void) { //delete "/proc/kernel_timer" entry remove_proc_entry("kernel_timer", NULL); } MODULE_LICENSE("Dual BSD/GPL"); module_init(kernel_timer_init); module_exit(kernel_timer_clearup);