【Linux设备驱动程序(第三版)】----定时器:Timer
2011-07-08 14:40
344 查看
【Linux设备驱动程序(第三版)】----定时器:Timer
jit.c
#include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> #include <linux/time.h> #include <linux/timer.h> #include <linux/proc_fs.h> #include <linux/spinlock.h> #include <linux/interrupt.h> #include <asm/hardirq.h> #include <linux/sched.h>//jiffies #include <linux/kernel.h> #include <linux/types.h>//u64 #include <linux/fs.h>//file_operations, file #include <linux/completion.h> #include <asm/uaccess.h>//copy_to_user & copy_from_user int delay = HZ; enum jit_files { JIT_BUSY, JIT_SCHED, JIT_QUEUE, JIT_SCHEDTO }; int tdelay = 10; struct jit_data { struct timer_list timer; struct tasklet_struct tlet; int hi; wait_queue_head_t wait; unsigned long prevjiffies; unsigned char *buf; int loops; }; int jit_fn(char *buf, char **start, off_t offset, int len, int *eof, void *data) { unsigned long j0, j1; wait_queue_head_t wait; init_waitqueue_head(&wait); j0 = jiffies; j1 = j0 + delay; switch((long)data){ case JIT_BUSY: while(time_before(jiffies, j1)) cpu_relax(); break; case JIT_SCHED: while(time_before(jiffies, j1)) schedule(); break; case JIT_QUEUE: wait_event_interruptible_timeout(wait, 0, delay); break; case JIT_SCHEDTO: set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(delay); break; } j1 = jiffies; len = sprintf(buf, "%9li %9li\n", j0, j1); *start = buf; return len; } int jit_currentime(char *buf, char **start, off_t offset, int len, int *eof, void *data) { struct timeval tv1; struct timespec tv2; unsigned long j1; u64 j2; j1 = jiffies; j2 = get_jiffies_64(); do_gettimeofday(&tv1); tv2 = current_kernel_time(); len = 0; len += sprintf(buf,"0x%08lx 0x%016Lx %10i.%06i\n" "%40i.%09i\n", j1, j2, (int) tv1.tv_sec, (int) tv1.tv_usec, (int) tv2.tv_sec, (int) tv2.tv_nsec); *start = buf; return len; } #define JIT_ASYNC_LOOPS 5 void jit_timer_fn(unsigned long arg) { struct jit_data *data = (struct jit_data *)arg; unsigned long j = jiffies; data->buf += sprintf(data->buf,"%9li %3li %i %6i %i %s\n",j,j-data->prevjiffies,in_interrupt()?1:0, current->pid, smp_processor_id(), current->comm); if(--data->loops){ data->timer.expires += tdelay; data->prevjiffies = j; add_timer(&data->timer); }else{ wake_up_interruptible(&data->wait); } } int jit_timer(char *buf, char **start, off_t offset, int len, int *eof, void *unused_data) { struct jit_data *data; char *buf2 = buf; unsigned long j = jiffies; data = kmalloc(sizeof(*data), GFP_KERNEL); if(!data) return -ENOMEM; init_timer(&data->timer); init_waitqueue_head(&data->wait); buf2 += sprintf(buf2," time delta inirq pid cpu command\n"); buf2 += sprintf(buf2,"%9li %3li %i %6i %i %s\n",j,0L,in_interrupt()?1:0, current->pid, smp_processor_id(), current->comm); data->prevjiffies = j; data->buf = buf2; data->loops = JIT_ASYNC_LOOPS; data->timer.data = (unsigned long)data; data->timer.function = jit_timer_fn; data->timer.expires = j + tdelay; add_timer(&data->timer); wait_event_interruptible(data->wait, !data->loops); if(signal_pending(current)) return -ERESTARTSYS; buf2 = data->buf; kfree(data); *eof =1; return buf2 - buf; } int __init jit_init(void) { create_proc_read_entry("jit_currentime", 0, NULL, jit_currentime, NULL); create_proc_read_entry("jitbusy", 0, NULL, jit_fn, (void *)JIT_BUSY); create_proc_read_entry("jitsched", 0, NULL, jit_fn, (void *)JIT_SCHED); create_proc_read_entry("jitqueue", 0, NULL, jit_fn, (void *)JIT_QUEUE); create_proc_read_entry("jitschedto", 0, NULL, jit_fn, (void *)JIT_SCHEDTO); create_proc_read_entry("jittimer", 0, NULL, jit_timer, NULL); return 0; } void __exit jit_exit(void) { remove_proc_entry("jit_currentime", NULL); remove_proc_entry("jitbusy", NULL); remove_proc_entry("jitsched", NULL); remove_proc_entry("jitqueue", NULL); remove_proc_entry("jitschedto", NULL); remove_proc_entry("jittimer", NULL); } MODULE_LICENSE("Dual BSD/GPL"); module_init(jit_init); module_exit(jit_exit);
Makefile
obj-m:= jit.o modules-objs:= jit.o KDIR:= /usr/src/linux-headers-2.6.31-14-generic/ PWD:= $(shell pwd) default: make -C $(KDIR) M=$(PWD) modules clean: rm -rf *.ko *.mod.c *.mod.o *.o *.markers *.symvers *.order
装载
insmod jit.ko
测试
cat /proc/jittimer
cat /proc/jittimer time delta inirq pid cpu command 3244715 0 0 7292 1 cat 3244725 10 1 4935 1 gnome-terminal 3244735 10 1 0 1 swapper 3244745 10 1 0 1 swapper 3244755 10 1 0 1 swapper 3244765 10 1 0 1 swapper
卸载
rmmod jit
相关文章推荐
- Linux 设备驱动程序 第三版
- Linux设备驱动程序第三版学习(7)- 高级字符驱动程序操作(续2)- poll/select
- 【Linux设备驱动程序(第三版)】----延迟:超时(wait_event_interruptible_timeout)
- Linux设备驱动程序第三版学习(4)- 并发和竟态
- 【Linux设备驱动程序(第三版)】----重要的数据结构
- 【Linux设备驱动程序(第三版)】----完成量completion
- 【Linux设备驱动程序(第三版)】----获取当前时间
- 【Linux设备驱动程序(第三版)】----延迟:超时(schedule_timeout)
- Linux设备驱动程序第三版学习(2)-字符设备驱动程序源码分析(续)
- 【Linux设备驱动程序(第三版)】----简单休眠 Sleepy
- Linux设备驱动之timer定时器与延时
- Linux设备驱动程序第三版学习(2)-字符设备驱动程序源码分析(续)
- 完整的Linux设备驱动程序 第三版
- 【Linux设备驱动程序(第三版)】----设备文件的访问控制:独享设备
- linux设备驱动程序第三版中译版
- Linux设备驱动程序第三版学习(5)- 高级字符驱动程序操作 - ioctl .
- Linux设备驱动程序第三版学习(6)- 高级字符驱动程序操作(续1)- 进程休眠 .
- 07-S3C2440驱动学习(一)嵌入式linux字符设备驱动-按键驱动程序之异步通知机制+原子操作+互斥信号量+阻塞与非阻塞+定时器去抖
- 【Linux设备驱动程序(第三版)】----模块参数
- 【Linux设备驱动程序(第三版)】----tasklet