Linux内核系统定时器TIMER实现过程分析

Linux系统定时器,在内核中扮演着重要角色。内核的许多重要实现如任务调度,工作队列等均以系统定时器关系密切。系统定时器能以可编程的频率中断处理,这一中断叫做软中断。此频率即为每秒的定时器节拍数HZ。HZ的越大,说明定时器节拍越小,线程调度的准确性会越高。但HZ设得过大,对一个系统来说并不好,会导CPU开销过大,反而造成任务调度效率降低。滴答jiffies 变量记录系统启动以来,系统定时器已经触发的次数。也就是说每过一秒jiffies的增量为HZ,一般HZ=100,HZ是可以配置的,在S3C2440 arm linux中配置为200.

下面基于Linux2.6.30.4源码来探讨其实现原理及其过程。

要理解系统定时器实现原理,先来看看关系到系统定时器的各种数据结构,其具体的描述参数。

结构体structtimer_list来描述timer的参数,其数据结构如下:

[cpp]
  1. struct timer_list {  
  2.        structlist_head entry;              //timer双向链表   
  3.        unsignedlong expires;             //timer超时变量   
  4.    
  5.        void(*function)(unsigned long);   //timer超时回调函数  www.linuxidc.com 
  6.        unsignedlong data;                  //传递给回调函数的数据,也就是定时器数据   
  7.       struct tvec_base *base;            //timer base向量表用于timer_list的挂载和链表管理   
  8.                                               //timer的一些扩展参数   
  9. #ifdef CONFIG_TIMER_STATS          
  10.        void*start_site;  
  11.        charstart_comm[16];  
  12.        intstart_pid;  
  13. #endif   
  14. #ifdef CONFIG_LOCKDEP   
  15.        structlockdep_map lockdep_map;  
  16. #endif   
  17. };  

其中:

[cpp]
  1. list_entry结构:  
  2. struct list_head {  
  3.        structlist_head *next, *prev;  
  4. };  
  5. tevc_base的结构:  
  6. struct tvec_base {  
  7.        spinlock_tlock;                         //自旋锁lock   
  8.        structtimer_list *running_timer;   //指向已经挂载进来的timer_list   
  9.        unsignedlong timer_jiffies;          //timer jiffies用于记录定时器当前jiffies   
  10.        structtvec_root tv1;                  //5组tvec_base,从tv1~tv5,成员数各不相同   
  11.        structtvec tv2;                        //其成员数TVR_SIZE,TVN_SIZE决定   
  12.        structtvec tv3;  
  13.        structtvec tv4;  
  14.        structtvec tv5;  
  15. } ____cacheline_aligned;  
  16.   
  17. #define TVN_BITS (CONFIG_BASE_SMALL ? 4 :6)   
  18. #define TVR_BITS (CONFIG_BASE_SMALL ? 6 :8)   
  19. #define TVN_SIZE (1 << TVN_BITS)   
  20. #define TVR_SIZE (1 << TVR_BITS)   
  21. #define TVN_MASK (TVN_SIZE - 1)   
  22. #define TVR_MASK (TVR_SIZE - 1)   
  23.    
  24. struct tvec {  
  25.        structlist_head vec[TVN_SIZE];   // tv2~t5个数为64的数组   
  26. };                              
  27.    
  28. struct tvec_root {  
  29.        structlist_head vec[TVR_SIZE];  //tv1个数为256的数组   
  30. };  

相关推荐