核心 核心定時器的使用

2021-05-31 22:16:51 字數 2297 閱讀 8558

概要

核心定時器是核心用來控制在未來某個時間點(基於jiffies)排程執行某個函式的一種機制,其實現位於 和 kernel/timer.c 檔案中。

被排程的函式肯定是非同步執行的,它類似於一種「軟體中斷」,而且是處於非程序的上下文中,所以排程函式必須遵守以下規則:

1) 沒有 current 指標、不允許訪問使用者空間。因為沒有程序上下文,相關**和被中斷的程序沒有任何聯絡。

2) 不能執行休眠(或可能引起休眠的函式)和排程。

3) 任何被訪問的資料結構都應該針對併發訪問進行保護,以防止競爭條件。

核心定時器的排程函式執行過一次後就不會再被執行了(相當於自動登出),但可以通過在被排程的函式中重新排程自己來週期執行。

在smp系統中,排程函式總是在註冊它的同一cpu上執行,以盡可能獲得快取的局域性。

定時器api

核心定時器的資料結構

struct timer_list ;

其中 expires 字段表示期望定時器執行的 jiffies 值,到達該 jiffies 值時,將呼叫 function 函式,並傳遞 data 作為引數。當乙個定時器被註冊到核心之後,entry 字段用來連線該定時器到乙個核心鍊錶中。base 欄位是核心內部實現所用的。

需要注意的是 expires 的值是32位的,因為核心定時器並不適用於長的未來時間點。

初始化

在使用 struct timer_list 之前,需要初始化該資料結構,確保所有的字段都被正確地設定。初始化有兩種方法。

方法一:

define_timer(timer_name, function_name, expires_value, data);

該巨集會定義乙個名叫 timer_name 核心定時器,並初始化其 function, expires, name 和 base 字段。

方法二:

struct timer_list mytimer;

setup_timer(&mytimer, (*function)(unsigned long), unsigned long data);

mytimer.expires = jiffies + 5*hz;

注意,無論用哪種方法初始化,其本質都只是給字段賦值,所以只要在執行 add_timer() 之前,expires, function 和 data 欄位都可以直接再修改。

關於上面這些巨集和函式的定義,參見 include/linux/timer.h。

註冊

定時器要生效,還必須被連線到核心專門的鍊錶中,這可以通過 add_timer(struct timer_list *timer) 來實現。

重新註冊

要修改乙個定時器的排程時間,可以通過呼叫 mod_timer(struct timer_list *timer, unsigned long expires)。mod_timer() 會重新註冊定時器到核心,而不管定時器函式是否被執行過。

登出

登出乙個定時器,可以通過 del_timer(struct timer_list *timer) 或 del_timer_sync(struct timer_list *timer)。其中 del_timer_sync 是用在 smp 系統上的(在非smp系統上,它等於del_timer),當要被登出的定時器函式正在另乙個 cpu 上執行時,del_timer_sync() 會等待其執行完,所以這個函式會休眠。另外還應避免它和被排程的函式爭用同乙個鎖。對於乙個已經被執行過且沒有重新註冊自己的定時器而言,登出函式其實也沒什麼事可做。

int timer_pending(const struct timer_list *timer)

這個函式用來判斷乙個定時器是否被新增到了核心鍊錶中以等待被排程執行。注意,當乙個定時器函式即將要被執行前,核心會把相應的定時器從核心鍊錶中刪除(相當於登出)

乙個簡單的例子

#include

#include

#include

struct timer_list mytimer;

static void myfunc(unsigned long data)

static int __init mytimer_init(void)

static void __exit mytimer_exit(void)

module_init(mytimer_init);

module_exit(mytimer_exit);

核心定時器的使用

核心定時器的使用 linux 核心定時器是核心用來控制在未來某個時間點 基於 jiffies 排程執行某個函式的一種機制,其實現位於 和kernel timer.c 檔案中。被排程的函式肯定是非同步執行的,它類似於一種 軟體中斷 而且是處於非程序的上下文中,所以排程函式必須遵守以下規則 1 沒有 c...

核心定時器的使用

概要 核心定時器是核心用來控制在未來某個時間點 基於jiffies 排程執行某個函式的一種機制,其實現位於 和 kernel timer.c 檔案中。被排程的函式肯定是非同步執行的,它類似於一種 軟體中斷 而且是處於非程序的上下文中,所以排程函式必須遵守以下規則 1 沒有 current 指標 不允...

核心定時器的使用

核心定時器的使用 linux 核心定時器是核心用來控制在未來某個時間點 基於 jiffies 排程執行某個函式的一種機制,其實現位於和 kernel timer.c 檔案中。被排程的函式肯定是非同步執行的,它類似於一種 軟體中斷 而且是處於非程序的上下文中,所以排程函式必須遵守以下規則 1 沒有 c...