内核提供给驱动许多函数来声明,注册,以及去除内核定时器. 下列的引用展示了基本的 代码块:
#include <linux/timer.h> struct timer_List
{
/* ... */
unsigned long expires;
voID (*function)(unsigned long); unsigned long data;
};
voID init_timer(struct timer_List *timer);
struct timer_List TIMER_INITIAliZER(_function,_expires,_data);
voID add_timer(struct timer_List * timer); int del_timer(struct timer_List * timer);
这个数据结构包含比曾展示过的更多的字段,但是这 3 个是打算从定时器代码自身以外 被存取的. 这个 expires 字段表示定时器期望运行的 jiffIEs 值; 在那个时间,这个 function 函数被调用使用 data 作为一个参数. 如果你需要在参数中传递多项,你可以 捆绑它们作为一个单个数据结构并且传递一个转换为 unsiged long 的指针,在所有支持 的体系上的一个安全做法并且在内存管理中相当普遍( 如同 15 章中讨论的 ). expires 值不是一个 jiffIEs_64 项因为定时器不被期望在将来很久到时,并且 64-位 *** 作在 32- 位平台上慢.
这个结构必须在使用前初始化. 这个步骤保证所有的成员被正确建立,包括那些对调用者 不透明的. 初始化可以通过调用 init_timer 或者 安排 TIMER_INITIAliZER 给一个静态 结构,根据你的需要. 在初始化后,你可以改变 3 个公共成员在调用 add_timer 前. 为 在到时前禁止一个已注册的定时器,调用 del_timer.
jit 模块包括一个例子文件,/proc/jitimer ( 为 "just in timer"),它返回一个头文 件行以及 6 个数据行. 这些数据行表示当前代码运行的环境; 第一个由读文件 *** 作产生 并且其他的由定时器. 下列的输出在编译内核时被记录:
phon% cat /proc/jitimer
time delta inirq pID cpu command 33565837 0 0 1269 0 cat
33565847 | 10 | 1 | 1271 | 0 | sh |
33565857 | 10 | 1 | 1273 | 0 | cpp0 |
33565867 | 10 | 1 | 1273 | 0 | cpp0 |
33565877 | 10 | 1 | 1274 | 0 | cc1 |
33565887 | 10 | 1 | 1274 | 0 | cc1 |
在这个输出,time 字段是代码运行时的 jiffIEs 值,delta 是自前一行的 jiffIEs 改 变值,inirq 是由 in_interrupt 返回的布尔值,pID 和 command 指的是当前进程,以 及 cpu 是在使用的 cpu 的数目( 在单处理器系统上一直为 0).
如果你读 /proc/jitimer 当系统无负载时,你会发现定时器的上下文是进程 0,空闲任 务,它被称为"对换进程"只要由于历史原因.
用来产生 /proc/jitimer 数据的定时器是缺省每 10 jiffIEs 运行一次,但是你可以在 加载模块时改变这个值通过设置 tdelay ( timer delay ) 参数.
下面的代码引用展示了 jit 关于 jitimer 定时器的部分. 当一个进程试图读取我们的文 件,我们建立这个定时器如下:
unsigned long j = jiffIEs;
/* fill the data for our timer function */ data->prevjiffIEs = j;
data->buf = buf2;
data->loops = JIT_ASYNC_LOOPS;
/* register the timer */
data->timer.data = (unsigned long)data; data->timer.function = jit_timer_fn;
data->timer.expires = j + tdelay; /* parameter */
add_timer(&data->timer);
/* wait for the buffer to fill */ wait_event_interruptible(data->wait,!data->loops);
The actual timer function looks like this: 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);
}
}
定时器 API 包括几个比上面介绍的那些更多的功能. 下面的集合是完整的核提供的函数 列表:
int mod_timer(struct timer_List *timer,unsigned long expires);
更新一个定时器的超时时间,使用一个超时定时器的一个普通的任务(再一次,关 马达软驱定时器是一个典型例子). mod_timer 也可被调用于非激活定时器,那里 你正常地使用 add_timer.
int del_timer_sync(struct timer_List *timer);
如同 del_timer 一样工作,但是还保证当它返回时,定时器函数不在任何 cpu 上 运行. del_timer_sync 用来避免竞争情况在 SMP 系统上,并且在 UP 内核中和 del_timer 相同. 这个函数应当在大部分情况下比 del_timer 更首先使用. 这个 函数可能睡眠如果它被从非原子上下文调用,但是在其他情况下会忙等待. 要十分 小心调用 del_timer_sync 当持有锁时; 如果这个定时器函数试图获得同一个锁,系统会死锁. 如果定时器函数重新注册自己,调用者必须首先确保这个重新注册不 会发生; 这常常同设置一个" 关闭 "标志来实现,这个标志被定时器函数检查.
int timer_pending(const struct timer_List * timer);
返回真或假来指示是否定时器当前被调度来运行,通过调用结构的其中一个不透明 的成员.
总结以上是内存溢出为你收集整理的linux 定时器 API全部内容,希望文章能够帮你解决linux 定时器 API所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)