linux定时器回调处理过程,Linux内核系统定时器TIMER实现过程分析
可見涉及到系統(tǒng)定時器的數(shù)據(jù)結(jié)構(gòu)并不多,那么:對于一個linux系統(tǒng)中,定時器個數(shù)可能會很多,而且每個定時器的超時事件時間并不相同,所以如何管理和處理定時器超時事件,關(guān)系到內(nèi)核性能的高低。它根據(jù)不同的定時事件,按時間間分組,將新增的timer定時器建成雙向鏈表,然后按照一定方式存放于5組tv1~tv5變量中稱為tec_base。對于對稱式多理器(SMP)系統(tǒng)還考慮到了TIMER從一個CPU遷移到另一個CPU的情況,相應(yīng)的tev_base也跟著更改。那它在系統(tǒng)是怎樣實現(xiàn)的呢?現(xiàn)在先從一個簡單的系統(tǒng)定時器應(yīng)用例子來看看它的實現(xiàn)過程:
[cpp]
#include?
#include?
#include?
structtimer_list???my_timer;
staticvoidmy_function(unsignedlongdata)
{
staticinti?=?0;
printk("timer’s?callback?function\n");
printk("timer’s?data?=?%lu\n",data);
return;
}
staticintmy_timer_init(void)
{
printk(“timerinit…\n”);
my_timer.data?=?0xff;
my_timer.function?=?my_function;
my_timer.expires?=?jiffies?+?3*HZ;
init_timer(&my_timer);
add_timer(&my_timer);
return0;
}
staticvoidmy_timer_exit(void)
{
printk("timer?exit…\n");
}
module_init(my_timer_init);
module_exit(my_timer_exit);
MODULE_AUTHOR("itspy");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("linux?kernel?timerprogramming");
上面例子,實現(xiàn)了一個定時器事件,將在3 HZ(秒)發(fā)生。my_imer_init函數(shù)中調(diào)用到的定時器API只有:
init_timer(&my_timer);?? //用于定時器初始化
add_timer(&my_timer);??? //增加一個新的定時器到tev_base向量表中
其中init_timer中調(diào)用了__init_timer(),這個函數(shù)才是真正初始化定時器的:
[cpp]
staticvoid__init_timer(structtimer_list*timer,
constchar*name,
structlock_class_key?*key)
{
timer->entry.next=?NULL;//對于新增的timer實例,其下一各總是指向NULL。
timer->base=?__raw_get_cpu_var(tvec_bases);//SMP中,獲得當(dāng)前處理器的tev_base
//這個tev_bases是根據(jù)一定規(guī)律變化的,稍后會將到
…
}
新增的定時器初始化,就是完成了一個timer_list結(jié)構(gòu)初始化過程。
add_timer() ?--> mod_timer() ?--> ?__mod_timer()其中:
[cpp]
staticinlineint
__mod_timer(structtimer_list?*timer,unsignedlongexpires,boolpending_only)
{
structtvec_base?*base,?*new_base;
unsignedlong?flags;
intret;
ret=?0;
BUG_ON(!timer->function);//?BUG檢測,確?;卣{(diào)函數(shù)為非空NULL
base=?lock_timer_base(timer,?&flags);//獲取本地cpu的tev_base,這是一個臨
//界資源,里邊是一個for(;;)循環(huán),如果找不到說明已經(jīng)遷移到了別的CPU
if(timer_pending(timer))?{//當(dāng)已掛載的timer?定時超時發(fā)生后,會被卸載摘除
detach_timer(timer,0);
ret=?1;
}else{
if(pending_only)//新增一個定時器時,pending_only?為?false
gotoout_unlock;
}
…
new_base=?__get_cpu_var(tvec_bases);//獲取本地cpu中的tevc_bases
if(base?!=?new_base)?{//由于之前base?可能已被遷移到其他CPU的?tev_base向量表,會造成?base?!=?new_base
if(likely(base->running_timer?!=?timer))?{//由于在timer正在運(yùn)行時,我們不能直接更改base,位與一個叫做DEFERRABLE(可延后標(biāo)志)后處理
/*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);//分析timer?expires及建表過程
out_unlock:
spin_unlock_irqrestore(&base->lock,flags);
returnret;
}
總結(jié)
以上是生活随笔為你收集整理的linux定时器回调处理过程,Linux内核系统定时器TIMER实现过程分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谁玩王者V区
- 下一篇: 第三代五菱宏光 MINIEV 马卡龙车型