tasklet机制与softirq

1、初始化

静态:DECLARE_TASKLET(name, func, data);

动态:

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)

{

      t->next = NULL;
      t->state = 0;
      atomic_set(&t->count, 0);
      t->func = func;
      t->data = data;

}

struct tasklet_struct mytasklet;    // 定义tasklet_struct结构体

tasklet_init(&mytasklet,  tasklet_handler, &mydata);   // 初始化 data可以是 变量/函数/结构体等的地址,如struct mydata mydata;

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的运行, 保证了原子操作。

原文地址:https://www.cnblogs.com/zhu-g5may/p/11391312.html