linux内核定时唤醒,Linux内核时钟与定时器的实现
五、好大一棵樹:高精度定時器的實(shí)現(xiàn)
在低精度下,級聯(lián)方式管理的定時
器非常地高效,每一次時鐘中斷,只需要判斷第一組下的表項(xiàng)(index = base->timer_jiffies & 255)是否有定時器即可。但到了高精度下,情況就不一樣了,老革命遇到了新問題,高精度定時器的定時精度為納級,而低精度下為毫秒級,
差了兩個數(shù)量級,每秒鐘就有1000000000個納秒。如果還按級聯(lián)方式來做的話,系統(tǒng)得有多少個表項(xiàng)啊,需要多少內(nèi)存啊。而且原來的級聯(lián)方式是根據(jù)jiffies和32位系統(tǒng)來做的,因此,最終系統(tǒng)采用了紅黑樹來管理定時器。更詳細(xì)的描述可以參考源碼樹的hrtimes.txt文件。
由于系統(tǒng)jiffies為毫秒級,而高精度定時器為納秒級,那么使用jiffies來表示已經(jīng)不合適了,因此,系統(tǒng)引入了ktime_t來表示時間,ktime_t實(shí)際為一個64bit的值,如果系統(tǒng)為32位,則為兩個32bit的聯(lián)合體。并引入了一堆接口做時間換算。
下面看看高精度定時器的觸發(fā)處理hrtimer_interrupt:
1,從紅黑樹取定時器節(jié)點(diǎn)(啟動定時器時已經(jīng)按照定時時間插入樹中),判斷是否超時,
2,處理定時器的回調(diào),
3,所有超時定時器已經(jīng)處理完畢,設(shè)置時鐘芯片下一個定時時間。
高精度定時器可以基于兩種時鐘,一個是單調(diào)時鐘,系統(tǒng)啟動為0開始遞增;一個是實(shí)際時間。
單調(diào)時鐘是不會變化的,而實(shí)際時間是有可能變化的,比如調(diào)用了settimeofday接口,這時候定時器怎么處理?
系統(tǒng)計(jì)算當(dāng)前時間與設(shè)置時間的差值,并從紅黑樹獲取第一個定時器節(jié)點(diǎn)(最先超時),超時時間加上差值(可能為正也可能為負(fù)),以此結(jié)果重新設(shè)置時鐘芯片的觸發(fā)時間。時鐘芯片觸發(fā)時,需要對每一個定時器進(jìn)行時間補(bǔ)償。
六、tick時鐘
沒有啟動動態(tài)時鐘的情況下,系統(tǒng)內(nèi)部有一個以固定周期觸發(fā)的定時器,它就是tick時鐘。
七、動態(tài)時鐘(tickless)
第六節(jié)tick時鐘介紹了系統(tǒng)的周期時鐘是以固定的時間間隔觸發(fā),超時處理函數(shù)進(jìn)行相應(yīng)的處理。但實(shí)際上,在不是很繁忙的系統(tǒng)上(最直觀的方法就是CPU占有率),大多數(shù)情況下,系統(tǒng)都是空閑的,由于該tick值較短(依賴于配置,常見的為10毫秒或者4毫秒),超時后發(fā)現(xiàn)沒有事情需要處理,又接著運(yùn)行IDLE任務(wù)或者CPU進(jìn)入節(jié)能狀態(tài),這個超時處理是很浪費(fèi)。考慮一個人,沒有事情做的時候想打個盹,但又怕錯過,不得不眼睛剛瞇上,又得睜開問有沒有事情做,還能睡好嗎?那能不能在只有事情處理的時候才叫醒他呢?
在內(nèi)核就實(shí)現(xiàn)了類似的機(jī)制,這就是動態(tài)時鐘。所謂動態(tài)時鐘,就是當(dāng)系統(tǒng)空閑時,它不是采用周期性的tick超時,而是判斷系統(tǒng)的下一個超時處理時間,如果超時處理時間大于1個tick值(小于則沒有啟動動態(tài)時鐘的意義),則對時鐘設(shè)備進(jìn)行編程,讓時鐘設(shè)備以單觸發(fā)的方式,在指定的超時時間觸發(fā)。簡單說,動態(tài)時鐘就是在空閑態(tài)下,系統(tǒng)節(jié)拍不是固定周期觸發(fā)的,是通過計(jì)算得出的,這就是動態(tài)的含義,可以認(rèn)為是tick周期時鐘的擴(kuò)展。
當(dāng)指定的超時時間到達(dá)之后或者被其他外部中斷提前喚醒后,系統(tǒng)為下一個時鐘信號編程,參見tick_nohz_restart_sched_tick->tick_nohz_restart
系統(tǒng)空閑時的相關(guān)處理函數(shù)參見cpu_idle->tick_nohz_stop_sched_tick。
相關(guān)數(shù)據(jù)結(jié)構(gòu)參見struct tick_sched(該結(jié)構(gòu)同時也是高精度定時器下的tick時鐘的實(shí)現(xiàn))。
特別的是,動態(tài)時鐘機(jī)制是否支持是在編譯時指定的,使能編譯宏CONFIG_NO_HZ才會支持。
總結(jié)
以上是生活随笔為你收集整理的linux内核定时唤醒,Linux内核时钟与定时器的实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: x86架构linux内核引导过程分析,S
- 下一篇: Linux系统没有home分区,我的li