电子发烧友App

硬声App

0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示
电子发烧友网>电子资料下载>嵌入式开发>Linux 时钟管理

Linux 时钟管理

2017-11-01 | rar | 0.6 MB | 次下载 | 1积分

资料介绍

 Linux 中的定时器
  在 Linux 内核中主要有两种类型的定时器。一类称为 timeout 类型,另一类称为 timer 类型。timeout 类型的定时器通常用于检测各种错误条件,例如用于检测网卡收发数据包是否会超时的定时器,IO 设备的读写是否会超时的定时器等等。通常情况下这些错误很少发生,因此,使用 timeout 类型的定时器一般在超时之前就会被移除,从而很少产生真正的函数调用和系统开销。总的来说,使用 timeout 类型的定时器产生的系统开销很小,它是下文提及的 timer wheel 通常使用的环境。此外,在使用 timeout 类型定时器的地方往往并不关心超时处理,因此超时精确与否,早 0.01 秒或者晚 0.01 秒并不十分重要,这在下文论述 deferrable timers 时会进一步介绍。timer 类型的定时器与 timeout 类型的定时器正相反,使用 timer 类型的定时器往往要求在精确的时钟条件下完成特定的事件,通常是周期性的并且依赖超时机制进行处理。例如设备驱动通常会定时读写设备来进行数据交互。如何高效的管理 timer 类型的定时器对提高系统的处理效率十分重要,下文在介绍 hrtimer 时会有更加详细的论述。
  内核需要进行时钟管理,离不开底层的硬件支持。在早期是通过 8253 芯片提供的 PIT(Programmable Interval Timer)来提供时钟,但是 PIT 的频率很低,只能提供最高 1ms 的时钟精度,由于 PIT 触发的中断速度太慢,会导致很大的时延,对于像音视频这类对时间精度要求更高的应用并不足够,会极大的影响用户体验。随着硬件平台的不断发展变化,陆续出现了 TSC(Time Stamp Counter),HPET(High Precision Event Timer),ACPI PM Timer(ACPI Power Management Timer),CPU Local APIC Timer 等精度更高的时钟。这些时钟陆续被 Linux 的时钟子系统所采纳,从而不断的提高 Linux 时钟子系统的性能和灵活性。这些不同的时钟会在下文不同的章节中分别进行介绍。
  Timer wheel
  在 Linux 2.6.16 之前,内核一直使用一种称为 timer wheel 的机制来管理时钟。这就是熟知的 kernel 一直采用的基于 HZ 的 timer 机制。Timer wheel 的核心数据结构如清单 1 所示:
  清单 1. 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;
  以 CONFIG_BASE_SMALL 定义为 0 为例,TVR_SIZE = 256,TVN_SIZE = 64,这样
  可以得到如图 1 所示的 timer wheel 的结构。
  Linux 时钟管理
  图 1. Timer wheel 的逻辑结构
  在 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)。如果 CONFIG_BASE_SMALL 定义为 1,则最终使用的 list_head 个数为 128 个(64+16+16+16+16),占用的内存更少,更适合嵌入式系统使用。Timer wheel 的处理逻辑如清单 2 所示:
  清单 2. timer wheel 的核心处理函数
  static inline void __run_timers(struct tvec_base *base)
  {
  struct timer_list *timer;
  spin_lock_irq(&base-》lock);
  while (time_after_eq(jiffies, base-》timer_jiffies)) {
  struct list_head work_list;
  struct list_head *head = &work_list;
  int index = base-》timer_jiffies & TVR_MASK;
  /*
  * Cascade timers:
  */
  if (!index &&
  (!cascade(base, &base-》tv2, INDEX(0))) &&
  (!cascade(base, &base-》tv3, INDEX(1))) &&
  !cascade(base, &base-》tv4, INDEX(2)))
  cascade(base, &base-》tv5, INDEX(3));
  ++base-》timer_jiffies;
  list_replace_init(base-》tv1.vec + index, &work_list);
  while (!list_empty(head)) {
  void (*fn)(unsigned long);
  unsigned long data;
  timer = list_first_entry(head, struct timer_list,entry);
  fn = timer-》function;
  data = timer-》data;
  。 . 。 .
  fn(data);
  。 . 。 .
  }
  base-》timer_jiffies 用来记录在 TV1 中最接近超时的 tick 的位置。index 是用来遍历 TV1 的索引。每一次循环 index 会定位一个当前待处理的 tick,并处理这个 tick 下所有超时的 timer。base-》timer_jiffies 会在每次循环后增加一个 jiffy,index 也会随之向前移动。当 index 变为 0 时表示 TV1 完成了一次完整的遍历,此时所有在 TV1 中的 timer 都被处理了,因此需要通过 cascade 将后面 TV2,TV3 等 timer list 中的 timer 向前移动,类似于进位。这种层叠的 timer list 实现机制可以大大降低每次检查超时 timer 的时间,每次中断只需要针对 TV1 进行检查,只有必要时才进行 cascade。即便如此,timer wheel 的实现机制仍然存在很大弊端。一个弊端就是 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 开始,一个新的 timer 子系统 hrtimer 被加入到内核中。
下载该资料的人也在下载 下载该资料的人还在阅读
更多 >

评论

查看更多

下载排行

本周

  1. 1TC358743XBG评估板参考手册
  2. 1.36 MB  |  330次下载  |  免费
  3. 2开关电源基础知识
  4. 5.73 MB  |  6次下载  |  免费
  5. 3100W短波放大电路图
  6. 0.05 MB  |  4次下载  |  3 积分
  7. 4嵌入式linux-聊天程序设计
  8. 0.60 MB  |  3次下载  |  免费
  9. 5基于FPGA的光纤通信系统的设计与实现
  10. 0.61 MB  |  2次下载  |  免费
  11. 6基于FPGA的C8051F单片机开发板设计
  12. 0.70 MB  |  2次下载  |  免费
  13. 751单片机窗帘控制器仿真程序
  14. 1.93 MB  |  2次下载  |  免费
  15. 8基于51单片机的RGB调色灯程序仿真
  16. 0.86 MB  |  2次下载  |  免费

本月

  1. 1OrCAD10.5下载OrCAD10.5中文版软件
  2. 0.00 MB  |  234315次下载  |  免费
  3. 2555集成电路应用800例(新编版)
  4. 0.00 MB  |  33564次下载  |  免费
  5. 3接口电路图大全
  6. 未知  |  30323次下载  |  免费
  7. 4开关电源设计实例指南
  8. 未知  |  21548次下载  |  免费
  9. 5电气工程师手册免费下载(新编第二版pdf电子书)
  10. 0.00 MB  |  15349次下载  |  免费
  11. 6数字电路基础pdf(下载)
  12. 未知  |  13750次下载  |  免费
  13. 7电子制作实例集锦 下载
  14. 未知  |  8113次下载  |  免费
  15. 8《LED驱动电路设计》 温德尔著
  16. 0.00 MB  |  6653次下载  |  免费

总榜

  1. 1matlab软件下载入口
  2. 未知  |  935054次下载  |  免费
  3. 2protel99se软件下载(可英文版转中文版)
  4. 78.1 MB  |  537796次下载  |  免费
  5. 3MATLAB 7.1 下载 (含软件介绍)
  6. 未知  |  420026次下载  |  免费
  7. 4OrCAD10.5下载OrCAD10.5中文版软件
  8. 0.00 MB  |  234315次下载  |  免费
  9. 5Altium DXP2002下载入口
  10. 未知  |  233046次下载  |  免费
  11. 6电路仿真软件multisim 10.0免费下载
  12. 340992  |  191185次下载  |  免费
  13. 7十天学会AVR单片机与C语言视频教程 下载
  14. 158M  |  183278次下载  |  免费
  15. 8proe5.0野火版下载(中文版免费下载)
  16. 未知  |  138040次下载  |  免费