核心定時器

2021-06-13 12:14:49 字數 1991 閱讀 2563

核心中最終的計時資源是定時器。定時器用於定時器超時處理程式在未來某個特定時間點執行,或者週期性的輪詢硬體的狀態。linux提供了核心定時器完成這類工作。

定 時器的只需要執行一些初始化的操作,如:設定乙個超時時間,指定超時要呼叫的函式,然後啟用定時器就可以了。它的處理和工作佇列還是有點類似的。和任務隊 列一樣,核心定時器並不是週期執行,它在超時後自動銷毀。因此,如果要實現週期輪詢,就需要在定時器執行函式返回前再次啟用定時器。我理解的是下面超時處 理函式中的add_timer(&polling_timer);就是再次啟用的作用,不知道是否準確。

一般來說,定時器都在超時後馬上就會執行超時處理函式,但是也有可能被推遲到下乙個時鐘節拍時才能執行,所以不能用定時器來實現任何硬實時任務。

下面看看乙個實現輪詢操作的小例子:

struct timer_list polling_timer;

init_timer(&polling_timer);

polling_timer.data = (unsigned long)something;

polling_timer.function = polling_handler;

polling_timer.expires = jiffies + 2 * hz;

add_timer(&polling_timer);

void polling_handler(unsigned long data) {

polling_timer.expires = jiffies + 2 * hz;

add_timer(&polling_timer); 

jiffies是linux核心中的乙個全域性變數,用來記錄自系統啟動以來產生的節拍的總數。啟動時,核心將該變數初始化為0,此後,每次時鐘中斷處理程式都會增加該變數的值。因為一秒內時鐘中斷的次數等於hz,所以jiffies一秒內增加的值也就為hz。系統執行時間以秒為單位計算,就等於jiffies/hz。

節拍率hz是通過靜態預處理定義的,在系統啟動時按照hz值對硬體進行設定。體系結構不同,hz值就不同,在i386體系結構在include/asm-i386/param.h中定義如下:

#define hz 1000

每秒鐘時鐘中斷1000次,也就是說,在1秒裡jiffies會被增加1000。因此jiffies + 2 * hz表示推後2秒鐘。

void init_timer(struct timer_list *timer);

該函式用來初始化定時器結構,其實它只將prev和next指標清零;

void add_timer(struct timer_list *timer);

該函式將定時器插入活動定時器的全域性佇列中,即啟用定時器;

void mod_timer(&polling_timer, jiffies + new_delay);

需要更改已經啟用的定時器的超時時間,則呼叫上面函式;

del_timer(&polling_timer);

如果需要在定時器超時前將定時器從鍊錶中刪除,則呼叫上面函式。注意:定時器超時後,系統會自動刪除定時器,則不用呼叫上面函式。

在多處理器的情況下使用:

del_timer_sync(&polling_timer);

和del_timer函式類似,不同的是該函式確保在它返回時,定時器函式不在任何cpu上執行,大多數情況下使用該函式。再次注意:不需要為已經超時的定時器呼叫該函式,因為系統會自動刪除。在已經從鍊錶刪除的定時器上呼叫del_timer()或del_timer_sync()沒什麼害處,所以說從定時器函式中刪除定時器是一種很好的習慣。

核心定時器是在時鐘中斷發生後,作為軟中斷在下半部的上下文中執行的。所有的定時器結構都以鍊錶的形式儲存。時鐘中斷發生後,核心 按鍊錶順序依次執行。因為核心定時器發生在軟中斷中,因此,定時器執行函式不能夠睡眠,也不能夠持有訊號量。如果對硬體的訪問需要使用訊號量同步,或者可 能睡眠(比如需要呼叫kmalloc記憶體分配,但是由於某種原因不能使用gfp_atomic標誌),就不能直接通過定時器來實現了。乙個變通的做法是在 核心定時器執行函式裡呼叫工作佇列,在工作佇列處理函式中實現對硬體的訪問。

核心定時器

linux核心2.4版中去掉了老版本核心中的靜態定時器機制,而只留下動態定時器。相應地在timer bh 函式中也不再通過 run old timers 函式來執行老式的靜態定時器。動態定時器與靜態定時器這二個概念是相對於linux核心定時器機制的可擴充套件 功能而言的,動態定時器是指核心的定時器佇...

核心定時器,

ldd3 當定時器執行時 排程該定時器的程序可能正在睡眠,或在其它處理器上執行,或乾脆推出。沒有執行定時器,排程它的程式推出了,定時器該如何?2.6.35。22核心 gcc 4.4.5 include include include include include include include i...

核心定時器

核心用來控制在未來某個時間點 基於jiffies 排程執行某個函式的一種機制。被排程的函式是非同步執行的,它類似於一種 軟體中斷 而且是處於非程序的上下文中,所以排程函式必須遵守以下規則 1 沒有 current 指標 不允許訪問使用者空間。因為沒有程序上下文,相關 和被中斷的程序沒有任何聯絡。2 ...