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