注册时钟事件监听器

原创 2011年01月11日 22:53:00

5.1.3 注册时钟事件监听器

由于我们在.config文件中设置了CONFIG_GENERIC_CLOCKEVENTS,所以,start_kernel函数的第558行调用kernel/time/tick-common.c中的tick_init函数,来注册一个时钟事件监听器。tick_init只调用一个clockevents_register_notifier函数:

 

static struct notifier_block tick_notifier = {

       .notifier_call = tick_notify,

};

 

void __init tick_init(void)

{

       clockevents_register_notifier(&tick_notifier);

}

 

int clockevents_register_notifier(struct notifier_block *nb)

{

       unsigned long flags;

       int ret;

 

       raw_spin_lock_irqsave(&clockevents_lock, flags);

       ret = raw_notifier_chain_register(&clockevents_chain, nb);

       raw_spin_unlock_irqrestore(&clockevents_lock, flags);

 

       return ret;

}

 

这个函数很简单,只要先明白一个notifier_block结构就行了:

struct notifier_block {

       int (*notifier_call)(struct notifier_block *, unsigned long, void *);

       struct notifier_block *next;

       int priority;

};

 

tick_notifier全局变量在编译vmlinux的时候其notifier_call被设置成了tick_notify函数:

 

static int tick_notify(struct notifier_block *nb, unsigned long reason,

                            void *dev)

{

       switch (reason) {

 

       case CLOCK_EVT_NOTIFY_ADD:

              return tick_check_new_device(dev);

 

       case CLOCK_EVT_NOTIFY_BROADCAST_ON:

       case CLOCK_EVT_NOTIFY_BROADCAST_OFF:

       case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:

              tick_broadcast_on_off(reason, dev);

              break;

 

       case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:

       case CLOCK_EVT_NOTIFY_BROADCAST_EXIT:

              tick_broadcast_oneshot_control(reason);

              break;

 

       case CLOCK_EVT_NOTIFY_CPU_DYING:

              tick_handover_do_timer(dev);

              break;

 

       case CLOCK_EVT_NOTIFY_CPU_DEAD:

              tick_shutdown_broadcast_oneshot(dev);

              tick_shutdown_broadcast(dev);

              tick_shutdown(dev);

              break;

 

       case CLOCK_EVT_NOTIFY_SUSPEND:

              tick_suspend();

              tick_suspend_broadcast();

              break;

 

       case CLOCK_EVT_NOTIFY_RESUME:

              tick_resume();

              break;

 

       default:

              break;

       }

 

       return NOTIFY_OK;

}

 

这上面一串函数是什么意思?这里要学一个新知识——通知链技术。我们知道内核一些驱动或文件系统是被编译成模块了的,当某个模块的某些事件对其模块是很有用的,则本模块应该定义一个通知链,并导出接口。

 

那么其它模块对其事件感兴趣时,可以调用这些接口注册(注销)当事件发生时的行为。而本模块在事件发生时,调用通知其链上的所有订阅者(调用其函数)。

 

而这个notifier_block就是通知链中的元素,记录了当发出通知时,应该执行的操作(即回调函数)。这里tick_notifier是一个时钟事件监听器模块,当发出通知是,就执行tick_notify函数。

 

所以,clockevents_register_notifier函数就调用raw_notifier_chain_register来注册,其实就是把三步:获得自旋锁、把tick_notifier加入clockevents_chain、释放自旋锁。

相关文章推荐

Cocos2dx引擎9-注册事件监听器

转载 http://www.2cto.com/kf/201410/342679.html 1、事件处理方法 下面为普通的点击事件监听器(下面简称EventListener)注册部分;注册Even...

【Android 开发教程】注册事件监听器

当用户与视图views进行交互的时候,views也会触发事件。举个例子,当用户点击了一个按钮,你需要为这个事件服务,只有这样,才能去执行某些适当的行为。如果想这么做的话,你就需要为视图views注册监...
  • manoel
  • manoel
  • 2012年05月19日 10:13
  • 3508

为Button点击事件注册监听器的两种方法

为Button点击事件注册监听器的两种方法
  • eyckwu
  • eyckwu
  • 2016年04月30日 14:39
  • 222

JavaSE第八十讲:监听器、事件、事件源、事件注册深度剖析

1. AWT事件处理 事件处理机制,几类具有典型代表意义的事件: 图80-1:几种常用事件处理机制 查看JDK Doc文档中的...

事件监听器

  • 2013年12月17日 00:04
  • 713KB
  • 下载

【Servlet3.0新特性】第02节_Servlet的动态注册以及使用注解编写监听器和过滤器

完整版见https://jadyer.github.io/2013/06/24/servlet30-new-feature/
  • jadyer
  • jadyer
  • 2013年06月24日 20:19
  • 1561

JList事件监听器的实现例子

  • 2016年09月01日 15:17
  • 5KB
  • 下载

java事件监听器

  • 2012年02月02日 09:38
  • 285KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:注册时钟事件监听器
举报原因:
原因补充:

(最多只允许输入30个字)