2007年10月5日 星期五

Linux Kernel: 簡介HZ, tick and jiffies

Linux核心幾個重要跟時間有關的名詞或變數,底下將介紹HZ、tick與jiffies。

HZ
Linux核心每隔固定週期會發出timer interrupt (IRQ 0),HZ是用來定義每一秒有幾次timer interrupts。舉例來說,HZ為1000,代表每秒有1000次timer interrupts。HZ可在編譯核心時設定,如下所示 (以核心版本2.6.20-15為例):
adrian@adrian-desktop:~$ cd /usr/src/linux
adrian@adrian-desktop:/usr/src/linux$ make menuconfig
Processor type and features ---> Timer frequency (250 HZ) --->

其中HZ可設定100、250、300或1000。以小弟的核心版本預設值為250。

小實驗
觀察/proc/interrupt的timer中斷次數,並於一秒後再次觀察其值。理論上,兩者應該相差250左右。
adrian@adrian-desktop:~$ cat /proc/interrupts | grep timer && sleep 1 && cat /proc/interrupts | grep timer
0: 9309306 IO-APIC-edge timer
0: 9309562 IO-APIC-edge timer

上面四個欄位分別為中斷號碼、CPU中斷次數、PIC與裝置名稱。



問題來了,timer interrupt會做哪些事情? 答案如下所列:
  • 更新時間、日期與系統從開機至目前經過多少時間 。
  • 更新系統資源使用率統計
  • 檢查正在執行的程序是否已經超過其所分配的執行時間額度。如果是的話,則侵佔(preempt)該程序以利執行其它等待執行的程序。
  • 檢查軟體時間器(Software timer,如alarm系統呼叫)跟時間延遲函式(Delay function)的延遲時間是否已經超過。
Tick
Tick是HZ的倒數,意即timer interrupt每發生一次中斷的時間。如HZ為250時,tick為4毫秒 (millisecond)。

Jiffies
Jiffies為Linux核心變數(32位元變數,unsigned long),它被用來紀錄系統自開幾以來,已經過多少的tick。每發生一次timer interrupt,Jiffies變數會被加一。值得注意的是,Jiffies於系統開機時,並非初始化成零,而是被設為-300*HZ (arch/i386/kernel/time.c),即代表系統於開機五分鐘後,jiffies便會溢位。那溢位怎麼辦? 事實上,Linux核心定義幾個macro(timer_after、time_after_eq、time_before與time_before_eq),即便是溢位,也能藉由這幾個macro正確地取得jiffies的內容。

另外,80x86架構定義一個與jiffies相關的變數jiffies_64 ,此變數64位元,要等到此變數溢位可能要好幾百萬年。因此要等到溢位這刻發生應該很難吧。那如何經由jiffies_64取得jiffies資訊呢? 事實上,jiffies被對應至jiffies_64最低的32位元。因此,經由jiffies_64可以完全不理會溢位的問題便能取得jiffies。

7 則留言:

我要成為嘴砲王 提到...
作者已經移除這則留言。
我要成為嘴砲王 提到...
作者已經移除這則留言。
我要成為嘴砲王 提到...

寫得真詳細阿,不知道您這些資訊從哪裡得到的,可以推薦網站或書本嗎?謝謝

Adrian Huang (黃圳柏) 提到...

Hi Frank,
沒留意到你有發表意見, 不好意思. 我是trace Linux核心得出的結論. 如果要書的話, "Linux Device Drivers, Third Edition", 這本書很棒你可以參考看看. Thanks.

Unknown 提到...

書上是寫32位元系統1000Hz約50天溢位,你寫到五分鐘溢位會不會太快了 @.@

Linux Device Drivers
Chapter 7 Tie, Delays, and Deffered Work p184.

Adrian Huang (黃圳柏) 提到...

Hi 聖恩,
在linux-source-2.6.31/kernel/timer.c有一段程式碼 u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES; ,其中INITIAL_JIFFIES被定義為#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) [linux-source-2.6.31/ include/linux/jiffies.h], 對於32位元系統, 於開機五分鐘便會溢位,我是從Linux原始碼trace而得出的結論。

Folay 提到...

稍微算了一下,在32位元的系統上,jiffies的確是在50天左右溢位