#define TIME_REQUESTS 64 static struct timer_list { long jiffies; void (*fn)(); struct timer_list * next; } timer_list[TIME_REQUESTS], * next_timer = NULL;
jiffies是定时器的到期时间,fn是定时器到期后将要执行的函数指针。
往内核添加定时器使用add_timer函数,代码如下:
void add_timer(long jiffies, void (*fn)(void)) { struct timer_list * p; if (!fn) return; cli(); if (jiffies <= 0) (fn)(); else { for (p = timer_list ; p < timer_list + TIME_REQUESTS ; p++) if (!p->fn) break; if (p >= timer_list + TIME_REQUESTS) panic("No more time requests free"); p->fn = fn; p->jiffies = jiffies; p->next = next_timer; next_timer = p; while (p->next && p->next->jiffies < p->jiffies) { p->jiffies -= p->next->jiffies; fn = p->fn; p->fn = p->next->fn; p->next->fn = fn; jiffies = p->jiffies; p->jiffies = p->next->jiffies; p->next->jiffies = jiffies; p = p->next; } } sti(); }
next_timer--->[0]--->NULL
next_timer--->[1]--->[0]--->NULL从上面可以看出,next_timer实际上是链表的一个头指针,而往链表新增一个节点实际上是在链表头部添加的。
void do_timer(long cpl) { /* ... */ if (next_timer) { next_timer->jiffies--; while (next_timer && next_timer->jiffies <= 0) { void (*fn)(void); fn = next_timer->fn; next_timer->fn = NULL; next_timer = next_timer->next; (fn)(); } } /* ... */ }假设定时器链表情况如下:
next_timer--->[1]--->[0]--->NULLnext_timer所指向的那个节点肯定是jiffies值最小的那个,应该是最先到期的,所以一个定时器中断来了之后jiffies值减1,如果jiffies值已经为0,即已经到期了,那么将next_timer指向下一个节点,同时调用已经到期的那个定时器的fn函数指针,如图:
next_timer--->[0]--->NULL