文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>2.6中小心用del_timer_sync

2.6中小心用del_timer_sync

时间:2006-11-27  来源:yfydz

2.6中小心用del_timer_sync   本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途。
msn: [email protected]
来源:http://yfydz.cublog.cn

1. 前言
del_timer_sync()是del_timer()的同步版,主要是在多处理器情况下使用,如果编译内核时不支持SMP,则是和del_timer()等价。 不过2.6下的del_timer_sync()和2.4相比有了较大改变,不小心就会造成内核死锁。   2. 函数实现 该函数在 kernel/timer.c 中实现。
2.1 2.4.26中的实现
/*
 * SMP specific function to delete periodic timer.
 * Caller must disable by some means restarting the timer
 * for new. Upon exit the timer is not queued and handler is not running
 * on any CPU. It returns number of times, which timer was deleted
 * (for reference counting).
 */
int del_timer_sync(struct timer_list * timer)
{
 int ret = 0;
 for (;;) {
  unsigned long flags;
  int running;
  spin_lock_irqsave(&timerlist_lock, flags);
  ret += detach_timer(timer);
  timer->list.next = timer->list.prev = 0;
  running = timer_is_running(timer);
  spin_unlock_irqrestore(&timerlist_lock, flags);
  if (!running)
   break;
  timer_synchronize(timer);
 }
 return ret;
}
函数体中主要调用detach_timer()函数和宏timer_is_running(),这两个处理都不是循环的,因此不会出现死循环情况,所以在哪调用这个函数都是安全的。 2.2 2.6.17中的实现
/***
 * del_timer_sync - deactivate a timer and wait for the handler to finish.
 * @timer: the timer to be deactivated
 *
 * This function only differs from del_timer() on SMP: besides deactivating
 * the timer it also makes sure the handler has finished executing on other
 * CPUs.
 *
 * Synchronization rules: callers must prevent restarting of the timer,
 * otherwise this function is meaningless. It must not be called from
 * interrupt contexts. The caller must not hold locks which would prevent
 * completion of the timer's handler. The timer's handler must not call
 * add_timer_on(). Upon exit the timer is not queued and the handler is
 * not running on any CPU.
 *
 * The function returns whether it has deactivated a pending timer or not.
 */
int del_timer_sync(struct timer_list *timer)
{
 for (;;) {
  int ret = try_to_del_timer_sync(timer);
  if (ret >= 0)
   return ret;
 }
}
2.6中的实现已经明确说明了该函数不能在中断上下文中调用:“It must not be called from interrupt contexts”,这里的中断上下文也就是定时器的处理函数timer.function,因为执行这个函数是在时钟中断中。 可看到该实现中就是循环调用try_to_del_timer_sync(),就是这个函数使得不能在中断上下文中使用: /*
 * This function tries to deactivate a timer. Upon successful (ret >= 0)
 * exit the timer is not queued and the handler is not running on any CPU.
 *
 * It must not be called from interrupt contexts.
 */
int try_to_del_timer_sync(struct timer_list *timer)
{
 tvec_base_t *base;
 unsigned long flags;
 int ret = -1;
// 取得timer的base
 base = lock_timer_base(timer, &flags);
// 如果base中正在运行的timer就是该timer的话,返回-1
// 返回-1后,del_timer_sync()会一直循环
// 所以如果在中断上下文中再次调用del_timer_sync(),内核将死锁
 if (base->running_timer == timer)
  goto out;
 ret = 0;
 if (timer_pending(timer)) {
  detach_timer(timer, 1);
  ret = 1;
 }
out:
 spin_unlock_irqrestore(&base->lock, flags);
 return ret;
}

3. 结论
  2.6中的del_timer_sync()的实现和2.4相比已经作了较大改变,绝对不能在定时处理函数中调用,而2.4中实际还是可以调用的,只是返回失败而已。所以一般情况都不要直接去调用定时函数,而是让时钟中断去处理它,可以通过改变中断时间的方法提前调用;如果非要调用,则必须在调用前就删除timer,而不是到该函数中去删除。
相关阅读 更多 +
排行榜 更多 +
风度

风度

游戏工具 下载
大姨妈月经提醒

大姨妈月经提醒

健康医疗 下载
海岸线小说网

海岸线小说网

浏览阅读 下载