可以看到这两个结构也就是hash链表.每次通过超时jiffies来计算slot,然后插入到链表.这里链表是FIFO的.这里除了tv5外其他几个都是简单的与TVR_MASK按位与计算.
Java代码
struct timer_list { struct list_head entry; ///超时节拍数 unsigned long expires; ///定时器将要执行的回调函数 void (*function)(unsigned long); ///传递给回调函数的参数 unsigned long data; ///从属于那个base struct tvec_base *base; }; struct timer_list { struct list_head entry; ///超时节拍数 unsigned long expires; ///定时器将要执行的回调函数 void (*function)(unsigned long); ///传递给回调函数的参数 unsigned long data; ///从属于那个base struct tvec_base *base; };///定义了一个per cpu变量.这里要知道定时器的注册和触发执行一定是在相同的cpu上的.struct tvec_base boot_tvec_bases;
static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases;
内核注册定时器最终都会通过调用internal_add_timer来实现.具体的工作方式是这样的:
1 如果定时器在接下来的0~255个jiffies中到期,则将定时器添加到tv1.
2 如果定时器是在接下来的256*64个jiffies中到期,则将定时器添加到tv2.
3 如果定时器是在接下来的256*64*64个jiffies中到期,则将定时器添加到tv3.
4 如果定时器是在接下来的256*64*64*64个jiffies中到期,则将定时器添加到tv4.
5 如果更大的超时,则利用0xffffffff来计算hash,然后插入到tv5(这个只会出现在64的系统).