一、初始化函數
靜態:DECLARE_TASKLET(name, func, data);atom
動態:隊列
struct tasklet_struct
{
struct tasklet_struct *next;
unsigned long state;
atomic_t count;
void (*func)(unsigned long);
unsigned long data;
};進程
void tasklet_init(struct tasklet_struct *t,
void (*func)(unsigned long), unsigned long data)it
{編譯
t->next = NULL;
t->state = 0;
atomic_set(&t->count, 0);
t->func = func;
t->data = data;變量
}並行
struct tasklet_struct mytasklet; // 定義tasklet_struct結構體call
tasklet_init(&mytasklet, tasklet_handler, &mydata); // 初始化 data能夠是 變量/函數/結構體等的地址,如struct mydata mydata;next
void tasklet_handler(unsigned long data) { // callback函數
struct mydata *p = (struct mydata *)data;
...
}
tasklet_schedule(&mytasklet); // 初始化以後須要交給tasklet_schedule來調度
tasklet_kill(&mytasklet); // 移除tasklet
與softirq的不一樣:tasklet只能在一個CPU上運行,而同一個softirq能夠同時在多個CPU core上運行;
軟中斷的靜態分配的,內核編譯好以後就不能改變,但tasklet就要靈活許多,好比動態加載模塊
因此在不須要並行運行軟中斷時就應該選擇tasklet
共同點:tasklet與softirq都不能睡眠,不能阻塞,只能被其餘中斷的上半部分打斷
工做隊列能夠睡眠,而且能夠具備更大的延時執行,tasklet代碼必須以原子方式執行,會在很短的時間很快地執行
工做隊列是在進程上下文執行,也就是執行過程當中運行其餘進程搶佔;而tasklet是在中斷上下文中運行,只有其餘中斷響應能夠打斷tasklet的運行, 保證了原子操做。