微執行緒(tasklet)
是一種更通用的下半部機制,大多數情況下應該優先使用微執行緒,只有在對效能要求非常高的時候才考慮使用軟中斷。然而,微執行緒是基於軟中斷的,它實際上是乙個軟中斷。核心中的微執行緒用兩個軟中斷表示:hi_softirq
和tasklet_softirq
。兩者唯一的區別在於hi_softirq
優先順序要高些。
資料結構
struct tasklet_struct ;
狀態state
的值可為0
,tasklet_state_sched,
tasklet_state_run
。tasklet_state_sched
表示某個微執行緒將被排程執行,而tasklet_state_run
表示某個微執行緒正在執行。
count
為微執行緒的引用計數,為非0
時表示微執行緒被禁用,不能執行。為0
時表示微執行緒可以執行,且如果標記為未決狀態,將可以執行。
排程微執行緒
被排程的微執行緒儲存於兩個每-cpu
結構中:tasklet_vec(
對於普通微執行緒)
和tasklet_hi_vec(
對於高優先順序微執行緒)
。這兩個結構都是tasklet_struct
結構構成的鍊錶。煉表表中的每個結點代表不同的微執行緒。排程微執行緒分別採用tasklet_schedule()
和tasklet_hi_schedule()
。大致步驟如下:
1.檢查微執行緒的狀態是否為tasklet_state_sched
。如果是,該微執行緒已經被排程,函式立即返回。
2.呼叫__tasklet_schedule()。3.
儲存中斷系統的狀態,然後禁用所有本地中斷。
4.將被排程的微執行緒新增到tasklet_vec
或tasklet_hi_vec
鍊錶的頭部。這些鍊錶對每個處理器來說是唯一的。
5.觸發tasklet_softirq
和hi_softirq
軟中斷,這樣使得do_softirq()
能在將來的某個時刻執行該微執行緒。(實質上就是將微執行緒標記為乙個未決的軟中斷)
6.恢復中斷到之前的狀態,然後返回。
這樣,do_softirq()
在某個時刻會執行這些未決的軟中斷,並執行相關的處理函式,即tasklet_action()
和tasklet_hi_action()
。這兩個函式是微執行緒處理的核心。執行的步驟如下:
1.禁用本地中斷,獲取本處理器上的tasklet_vec
和tasklet_hi_vec
鍊錶。2.
清除鍊錶。
3.啟動本地中斷。
4.遍歷鍊錶中的每個未決微執行緒。
5.如果是處理器空閒,檢測微執行緒是否執行於另外乙個處理器,即檢測tasklet_state_run
標誌。如果是,跳過,處理下乙個微執行緒。
6.如果否,設定tasklet_state_run
,這樣就不會在另乙個處理器上執行。
7.檢測微執行緒的引用數是否為0
,以確認微執行緒是否使能。如果否,跳過,處理下乙個微執行緒。
8.執行微執行緒處理函式。
9.清除微執行緒state
域的tasklet_state_run
標記。10.
重複上述過程,直到完畢。
使用微執行緒
靜態宣告
declare_tasklet(name,func, data)
declare_tasklet_disabled(name,func, data);
例子如下:
declare_tasklet(my_tasklet,my_tasklet_handler, dev);
等價於:
struct tasklet_struct my_tasklet = ;
動態宣告
tasklet_init(t,tasklet_handler, dev); /* dynamically as opposed to statically */
編寫自己的微執行緒處理函式
函式原型:void tasklet_handler(unsigned long data)
跟軟中斷一樣,微執行緒不能睡眠,所以不能使使用者訊號量等機制。
排程微執行緒
排程微執行緒使用如下函式:
tasklet_schedule(&my_tasklet);/* mark my_tasklet as pending */
其實質就是將微執行緒標記為未決狀態。
通過函式tasklet_disable()
來禁用乙個微執行緒,如果被禁用的微執行緒正在執行,函式將等待微執行緒執行完畢後,返回。函式tasklet_disable_nosync()
將立即返回。函式tasklet_enable()
使能乙個微執行緒。
tasklet使用模板
usingtasklets to offload work from interrupt handlers
struct roller_device_struct;
void__init roller_init()
/*the bottom half */
void
roller_analyze()
/*the interrupt handler */
static irqreturn_t
roller_interrupt(int irq, void *dev_id)
下半部機制之軟中斷
軟中斷 softirq 是用軟體方式模擬硬體中斷的概念,實現巨集觀上的非同步執行效果。softirq是基本的下半部機制,需要互斥使用。一般很少直接使用。通常只用在少數效能比較關鍵的子系統中。它是可重入的,允許乙個softirq的不同例項可同時執行在不同的處理器上。軟中斷的 位於kernel soft...
下半部機制之工作佇列
工作佇列是一種不同於軟中斷和微執行緒的一種下半部延遲機制。工作佇列將工作延遲到乙個核心執行緒中執行,它執行在程序上下文中,它是可排程的,並且可以休眠。通常,如果延遲的工作中需要休眠,就使用工作佇列,否則使用軟中斷或微執行緒。由於核心開發者反對建立乙個新的核心執行緒,因此,應當盡量使用工作佇列,它其實...
中斷處理 上下半部機制
首先需要了解一下中斷的概念 乙個 中斷 僅僅是乙個訊號,當硬體需要獲得處理器對它的關注時,就可以傳送這個訊號。核心維護了乙個中斷訊號線的登錄檔,該登錄檔類似於i o埠的登錄檔。模組在使用中斷前要先請求乙個中斷通道 或中斷請求irq 然後在使用後釋放該通道。用到的api就是request irq 以及...