Linux內核-定時測量

1、定時測量概念

定時測量作用:

跟蹤時間

聯合內核活動(如檢查超時)來驅使進程切換

組成:由基於固定頻率振盪器計數器的幾個硬件電路完成

Linux內核必需完成的兩種定時測量

保存當前的時間和日期

維持定時器,告訴內核或用戶程序某一時間間隔已經過去。

 

2、時鐘和定時器電路

  在80x86體系結構上,內核必須顯示地與幾種時鐘和定時器電路打交道。時鐘電路同時用於跟蹤當前時間和產生精確的時間度量定時器電路由內核編程,它們以固定的、預先定義的頻率發出中斷

2.1 實時時鐘

1、所有PC都包含一個實時時鐘,獨立與CPU和其他芯片

2、靠一個小電池或蓄電池供電,當PC被切斷電源,RTC還繼續工作

3、RTC能在IRQ8上發出週期性的中斷,頻率在2~8192 Hz之間

4、可以對RTC進行編程以使RTC達到某個特定的值時激活IRQ8線,--作爲一個鬧鐘來工作

5、Linux只用RTC來獲取時間和日期;不過通過對/dev/rtc設備文件進行操作,也允許進程對RTC編程

2.2 時間戳計數器(TSC

1、在80x86微處理器中,通過CLK輸入引線,接收外部振盪器的時鐘信號

2、在每個時鐘信號到來時加1

3、利用64位的時間戳計算器(TSC)寄存器來實現,可以通過彙編語言指令rdtsc讀這個寄存器

4.Linux通過這個寄存器可以獲得更精確的時間測量

Linux在初始化系統的時候必須確定時鐘信號的頻率。 算出CPU實際頻率的任務是在系統初始化期間完成的。calibrate_tsc()函數通過計算一個大約在5ms的時間間隔內產生的時鐘信號的個數來算出CPU實際的頻率。 通過適當地設置可編程間隔定時器的一個通過來產生這個時間常量

2.3 可編程間隔定時器(PIT)

1、PIC計算器16位,經過適當編程後,可以週期性的給出時鐘中斷,通知內核一個時間間隔已經過去

2、PIT永遠以內核確定的固定頻率不停地發出全局性的中斷,系統中的任一CPU都可以對其處理

3、PIT通過使用0x40~0x43 I/O斷開的一個8254 CMOS芯片

4、PIC有其自己的內部時鐘振盪器,可以靈活的編程

5、LINXU 給PC的第一個PIT進行編程,使它以(大約)1000Hz的頻率向IRQ0發出時鐘中斷,即每1ms產生一次時鐘中斷

2.4 CPU本地定時器

1、一種能夠產生單步中斷或週期性中斷的設備

2、APIC定時器把中斷只發給自己的處理器

3、APIC定時器是基於總線時鐘信號的,每個1,2,4,8,16,32,64128總線時鐘信號到來時對該定時器進行遞減可以實現對其編程的目的

2.5 高精度事件定時器(HPET

1、高精度事件定時器是由Intel和Microsoft聯合開發的一種新型定時器芯片。

2、HPET提供了許多可以被內核使用的硬定時器

3、定時器芯片主要包含8個32位或64位的獨立計算器。每個計算器由他自己的時鐘信號所驅動,該時鐘信號的頻率必須至少爲10MHZ,因此計數器最少可以每100ns增長一次。

4、任何計數器最多可以與32個定時器相關聯,每個定時器由一個比較器和一個匹配寄存器組成。(比較器是一組用於檢測計數器中的值與匹配寄存器中的值是否匹配的電路,如果找到一組匹配值就產生一個硬件中斷。)

5、定時器可以被激活產生週期性中斷。

6、可以通過映射到內存空間的寄存器對HPET芯片編程。HPET寄存器允許內核對計數器和匹配寄存器的值進行讀和寫。允許內核對單步中斷進行編程,允許內核在支持HPET的定時器上激活或禁止週期性中斷

2.6 ACPI 電源管理定時器

1、被稱作ACPI PMT 是一種時鐘設備,包含在幾乎所有基於ACPI的主板上。

2、時鐘信號擁有大約爲3.58MHz的固定頻率,該設備實際上是一個簡單的計算器,在每個時鐘節拍到來時增加一次。

3、如果操作系統或者BIOS可以通過動態降低CPU的工作頻率或者工作電壓來節省電池的電能,那麼ACPI電源管理定時器就比TSC更優越。

3、Linux計時體系結構

Linux 計時體系結構:是一組與時間流相關的內核數據結構和函數。

Linux 必定執行與定時相關的操作,比如內核週期性地:

1、更新自系統啓動以來所經過的時間 (clock_gettime)

2、更新時間和日期time/gettimeofday)。

3、確定當前進程在每個CPU上已運行了多長時間,如果已經超過了分配給它的時間,則搶佔它。

4、檢查每個軟定時器的時間間隔是否已到

 

兩種計時體系結構:

1、單處理系統上,所有的計時活動都是由全局定時器(可編程間隔定時器或高精度事件定時器)產生的中斷觸發

2、多處理系統上,所有普通的活動(像軟定時器的處理)都是由全局定時器產生的中斷觸發,而具體CPU的活動(像監控當前運行進程的執行時間)是由本地APIC定時器產生的中斷觸發

3.1 計時體系的數據結構和變量

timer_opts 數據結構的各個字段:

 

 3.2 單處理器計時體系結構

3.3 多處理器計時體系結構

4、軟定時器和延遲函數

定時器是一種軟件功能,即允許在將來的某個時刻,函數在給定的時間間隔用完被調用超時表示與定時器相關的時間間隔已經用完的那個時刻

  1. 軟定時器
    • 動態定時器(內核)
    • 間隔定時器(可以用戶

延遲函數

4.1 動態定時器

動態定時器:被動態地創建和撤消,對當前活動動態定時器的個數沒有限制

timer_list結構中

struct timer_list{

struct list_head entry; //用於將軟定時器插入雙向循環鏈表隊列中

unsigned long expires;// 給出定時器到期時間,時間用節拍數表示,其值爲系統啓動以來//所經歷過的節拍數

spinlock_t lock;

unsigned longmagic;

void(*function)(unsigned long); //包含定時器到期時執行函數的地址

unsigned long data; //指定傳遞給定時器函數的參數。正是由於data字段,就可以定義一個//單獨的通用函數來處理多個設備驅動程序的超時問題,在data字段可以存放設備ID,或其//它有意義的數據,定時器函數可以用這些數據區分不同的//設備。

tvec_base_t *base;

};

4.2 動態定時器競爭

被異步激活的的動態定時器有參與競爭條件的傾向。例如,考慮一個動態定時器,它的函數作用於可丟棄的資源。

如果在定時器函數被激活時資源不存在,那麼不停止定時器就釋放資源勢必導致數據結構的崩潰。因此,一種憑經驗的做法就是在釋放資源前停止定時器:

內核提供了del_timer_sync()函數。這個函數從鏈表中刪除定時器,然後檢查定時器函數是否還在其它CPU上運行;如果是,del_timer_sync()就等待,直到定時器函數結束。

修改已激活定時器expires字段的正確方法是調用mod_timer(),而不是刪除定時器隨後又創建它。在後一種方法中,要修改同一定時器expires字段的兩個內核控制路徑可能糟糕地交錯在一起。定時器函數在SMP上的安全實現是通過每個timer_list對象包含的lock自旋鎖達到的:每當內核必須訪問動態定時器的鏈表時,就禁止中斷並獵取這個自旋鎖。

4.3 動態定時器處理

儘管軟定時器具有巧妙的數據結構,但是對其處理是一種耗時的活動,所以不應該被時鐘中斷處理程序執行。在Linux.6中該活動由延遲函數來執行,也就是由TIMER_SOFTIRQ軟中斷行

run_timer_softirq()函數是與TIMER_SOFTIRQ軟中斷請求相關的可延遲函數。它實質上執行如下操作:

4.4 延遲函數

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章