定时器的比较

本文深入探讨Linux系统中的TimerWheel和Hrtimer数据结构与算法,详细解析其核心原理、时间精度以及应用实例,同时对比UCOS-II中的定时器处理过程,为开发者提供全面的技术指南。

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的处理过程如下图所示。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值