定时器的比较

来源:互联网 发布:欧洲 旅游 大学生 知乎 编辑:程序博客网 时间:2024/05/16 01:30

Linux系统

Timer Wheel

一、数据结构

核心数据结构为timer wheel

其核心数据结构为

                                  

 #define TVN_BITS (CONFIG_BASE_SMALL? 4 : 6)

 #define TVR_BITS (CONFIG_BASE_SMALL? 6 : 8)

 #define TVN_SIZE (1 <<TVN_BITS)

 #define TVR_SIZE (1 <<TVR_BITS)

 #define TVN_MASK (TVN_SIZE - 1)

 #define TVR_MASK (TVR_SIZE - 1)

 

 struct tvec {

        struct list_headvec[TVN_SIZE];

 };

 

 struct tvec_root {

        struct list_headvec[TVR_SIZE];

 };

 

 struct tvec_base {

        spinlock_t lock;

        struct timer_list*running_timer;

        unsigned long timer_jiffies;

        unsigned long next_timer;

        struct tvec_root tv1;

        struct tvec tv2;

        struct tvec tv3;

        struct tvec tv4;

        struct tvec tv5;

 } ____cacheline_aligned;

 

其中timerwheel的数据结构为

在 timer wheel 的框架下,所有系统正在使用的 timer 并不是顺序存放在一个平坦的链表中,因为这样做会使得查找,插入,删除等操作效率低下。Timer wheel 提供了 5 个 timer 数组,数组之间存在着类似时分秒的进位关系。TV1 为第一个 timer 数组,其中存放着从 timer_jiffies(当前到期的 jiffies)到 timer_jiffies + 255 共 256 个 tick 对应的 timer list。因为在一个 tick 上可能同时有多个 timer 等待超时处理,timer wheel 使用 list_head 将所有 timer 串成一个链表,以便在超时时顺序处理。TV2 有 64 个单元,每个单元都对应着 256 个 tick,因此 TV2 所表示的超时时间范围从 timer_jiffies + 256 到 timer_jiffies + 256 * 64 – 1。依次类推 TV3,TV4,TV5。以 HZ=1000 为例,每 1ms 产生一次中断,TV1 就会被访问一次,但是TV2 要每 256ms 才会被访问一次,TV3 要 16s,TV4 要 17 分钟,TV5 甚至要 19 小时才有机会检查一次。最终,timer wheel 可以管理的最大超时值为 2^32。一共使用了 512 个 list_head(256+64+64+64+64)。

 

 

*上图表示的不是很明确,实际上为树形结构。

可以知道时间精度为1ms

 

二、算法

 

 

 

 

Hrtimer

一、数据结构

Struct timespec{

         __kernel_time_t tv_sec;

         Long                               tvv_nsec;

};

表示自1970年经过的时间

struct timeval { 
    __kernel_time_t          tv_sec;          /* seconds */ 
    __kernel_suseconds_t    tv_usec;         /* microseconds */ 
 }; 
表示时间间隔,单位为微妙
union ktime { 
        s64     tv64; 
 #if BITS_PER_LONG != 64 && !defined(CONFIG_KTIME_SCALAR) 
        struct { 
 # ifdef __BIG_ENDIAN 
        s32     sec, nsec; 
 # else 
        s32     nsec, sec; 
 # endif 
        } tv; 
 #endif 
 }; 
核心数据结构 64bit
typedef u64 cycle_t;

表示时钟源中读取的类型

二、算法

 

 

hrtime_run_queues

 

 

ucos-II

timer wheel

一、数据结构

定时器控制块(OS_TMR)

 

OS_TMR OSTmrThl[OS_TMR_CFG_MAX];

OS_TMR *OSTmrFreeList;

OS_TMR_WHEEL OSTmrWheelTbl[OS_TMR_CFG_WHEEL_SIZE];

         其中,OSTmrThl为静态分配的所有OS_TMR,所有的定时器都包含在这个数组中。

         OSTmrFreeList则是空闲列表的表头,连接着所有的空闲定时器。

         和Linux中的timer wheel类似,这里面如下图所示,各个分组中存放的定时器为,各个定时器对OS_TMR_CFG_WHEEL_SIZE求模得到相同值的定时器在同一组中。

图 1

二、算法

创建定时器

OS_TMR *OSTmrCreate

删除定时器

BOOLEAN OSTmrDel

获取下次超时时间

INT32U OSTmrRemainGet

获取定时器状态

INT8U OSTmrStateGet

启动定时器

BOOLEAN OSTmrStart

停止定时器

BOOLEAN OSTmrStop

 

 

针对timer wheel的处理过程如下图所示。