Linux时间管理 (二)

1.1      Wheel时钟的实现(低精度定时器的实现)

通常OS操作系统都支持Wheel方式,例如LinuxNecluesvxworks都支持100-200Hz的节拍时钟。通过节拍OS进行时钟刷新以及产生任务调度,而每个硬件节拍就称为tick

1.1.1        核心数据结构

Linux 2.6.16之前,内核一直使用一种称为timer wheel(定时器轮)的机制来管理时钟。这就是kernel一直采用的基于HZtimer机制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_head vec[TVN_SIZE];

 };

 struct tvec_root {

        struct list_head vec[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;

 

SMP系统中,通过如下方式定义per-cpu变量:

struct tvec_base boot_tvec_bases;

EXPORT_SYMBOL(boot_tvec_bases);

static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases;

在内存较小的系统中可以设置CONFIG_BASE_SMALL选项为1来减少内存的使用。

1.1.2       定时器到期处理

对所有定时器的处理都由update_process_times发起,具体的调用流程如下:

update_process_times

    run_local_timers

        hrtimer_run_queues

        raise_softirq(TIMER_SOFTIRQ)

init_timers初始化时设置TIMER_SOFTIRQ的软中处理函数为run_timer_softirq,那么在run_timer_softirq将完成对到期的定时器实际的处理工作。其调用流程如下:

run_timer_softirq

    __run_timers

 

一个弊端就是cascade开销过大。在极端的条件下,同时会有多个TV需要进行cascade处理,会产生很大的时延。这也是为什么说timeout类型的定时器是timer wheel的主要应用环境,或者说timer wheel是为timeout类型的定时器优化的。因为timeout类型的定时器的应用场景多是错误条件的检测,这类错误发生的机率很小,通常不到超时就被删除了,因此不会产生 cascade的开销。另一方面,由于timer wheel是建立在 HZ 的基础上的,因此其计时精度无法进一步提高。毕竟一味的通过提高 HZ 值来提高计时精度并无意义,结果只能是产生大量的定时中断,增加额外的系统开销。因此,有必要将高精度的 timer 与低精度的 timer 分开,这样既可以确保低精度的 timeout 类型的定时器应用,也便于高精度的 timer 类型定时器的应用。还有一个重要的因素是 timer wheel 的实现与 jiffies 的耦合性太强,非常不便于扩展。因此,自从2.6.16开始, hrtimer这个新的timer子系统被加入到内核中。

 

1.2    Linux Wheel时钟的初始化过程

kernel启动的时候完成对Linux Wheel的核心数据结构的初始化工作。具体的初始化流程为

start_kernel

       init_timers

              timer_cpu_notify

                     init_timers_cpu

              init_timer_stats

              register_cpu_notifier

open_softirq

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值