快速业务通道

Linux 时钟处理机制(二)

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-04-27

  3.3 添加或删除软件时钟

  在了解了软件时钟的数据组织关系之后,现在来看一下如何添加以及删除一个软件时钟.

  3.3.1 添加软件时钟

  在 Linux 内核中要添加一个软件时钟,分配 struct timer_list 类型的变量,然后调用函数 add_timer() 将该软件时钟添加到相应调用 add_timer 函数的 CPU 的 base 中. Add_timer 是对函数 __mod_timer() 的一层包装.函数 __mod_timer() 的代码如清单3-2:

  清单3-2 __mod_timer 函数

  int __mod_timer(struct timer_list *timer, unsigned long expires){ struct tvec_base *base, *new_base; unsigned long flags; int ret = 0; …… base = lock_timer_base(timer, &flags); if (timer_pending(timer)) { detach_timer(timer, 0); ret = 1; } new_base = __get_cpu_var(tvec_bases); if (base != new_base) { if (likely(base->running_timer != timer)) { /* See the comment in lock_timer_base() */ timer_set_base(timer, NULL); spin_unlock(&base->lock); base = new_base; spin_lock(&base->lock); timer_set_base(timer, base); } } timer->expires = expires; internal_add_timer(base, timer); spin_unlock_irqrestore(&base->lock, flags); return ret;}

  代码解释:

  注:卸载软件时钟的意思是指将软件时钟从软件时钟所在 base 中删除,以后所说的卸载软件时钟也都是这个意思

  取得软件时钟所在 base 上的同步锁( struct tvec_base 变量中的自旋锁),并返回该软件时钟的 base ,保存在 base 变量中

  如果该软件时钟处在 pending 状态(在 base 中,准备执行),则卸载该软件时钟

  取得本 CPU 上的 base 指针(类型为 struct tvec_base* ),保存在 new_base 中

  如果 base 和 new_base 不一样,也就是说软件时钟发生了迁移(从一个 CPU 中移到了另一个 CPU 上),那么如果该软件时钟的处理函数当前没有在迁移之前的那个 CPU 上运行,则先将软件时钟的 base 设置为 NULL ,然后再将该软件时钟的 base 设置为 new_base .否则,跳到5.

  设置软件时钟的到期时间

  调用 internal_add_timer 函数将软件时钟添加到软件时钟的 base 中(本 CPU 的 base )

  释放锁

  这里有必要详细说明一下软件时钟如何被添加到软件时钟的 base 中的(添加到本 CPU base 的 tv1~tv5 里面),这是软件时钟处理的基础.来看函数 internal_add_timer 函数的实现,如清单3-3

  清单3-3 internal_add_timer 函数

  static void internal_add_timer(struct tvec_base *base, struct timer_list *timer){ unsigned long expires = timer->expires; unsigned long idx = expires - base->timer_jiffies; struct list_head *vec; if (idx < TVR_SIZE) { int i = expires & TVR_MASK; vec = base->tv1.vec i; } else if (idx < 1 << (TVR_BITS TVN_BITS)) { int i = (expires >> TVR_BITS) & TVN_MASK; vec = base->tv2.vec i; } else if (idx < 1 << (TVR_BITS 2 * TVN_BITS)) { int i = (expires >> (TVR_BITS TVN_BITS)) & TVN_MASK; vec = base->tv3.vec i; } else if (idx < 1 << (TVR_BITS 3 * TVN_BITS)) { int i = (expires >> (TVR_BITS 2 * TVN_BITS)) & TVN_MASK; vec = base->t

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号