概述
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、释放自旋锁。
最后
以上就是标致朋友为你收集整理的注册时钟事件监听器的全部内容,希望文章能够帮你解决注册时钟事件监听器所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复