[linux内核]中断下半部分——tasklet
1,Tasklet的概念
tasklet是利用软中断实现的一种下半部机制,tasklet由两类软中断的代表,HI_SOFTIRQ和TASKLET_SOFTIRQ,这两个的区别是HI_SOFTIRQ类型的软中断先于TASKLET_SOFTIRQ类型的软中断先执行。
tasklet由tasklet_struct结构表示,每个结构单独代表一个tasklet,在interrupt.h中定义。
- 420 struct tasklet_struct
- 421 {
- 422 struct tasklet_struct *next;
- 423 unsigned long state; //state成员的值在0,TASKLET_STATE_SCHED和TASKLET_STATE_RUN之间取值,TASKLET_STATE_SCHED表明该tasklet已经被调度正准备投入运行。
- 424 atomic_t count; //tasklet的引用计数,如果它不为0则tasklet被禁止,
- 425 void (*func)(unsigned long);
- 426 unsigned long data;
- 427 };
tasklet由tasklet_schedule()函数进行调度,
- <span style="font-weight: bold; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">2,Tasklet机制</span>
1)声明自己的Tasklet
静态创建:
既可以使用<linux/interrupt.h>中定义的两个宏中的一个DECLARE_TASKLET或DECLARE_TASKLET_DISABLED来静态创建tasklet,前者把创建的tasklet的引用计数器设置为0,该tasklet处于激活状态。另一个把引入计数器设为1,所以该tasklet处于禁止状态。还可以使用tasklet_init()动态创建一个tasklet。
- 429 #define DECLARE_TASKLET(name, func, data) \
- 430 struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data }
动态创建:
- struct msdc_host{
- struct tasklet_struct card_tasklet;
- };
- struct msdc_host *host;
- tasklet_init(&host->card_tasklet,msdc_tasklet_card,unsigned long arg);//msdc_tasklet_card是tasklet处理函数
- tasklet_hi_schedule(&host->card_tasklet);
- 470 void tasklet_init(struct tasklet_struct *t,
- 471 void (*func)(unsigned long), unsigned long data)
- 472 {
- 473 t->next = NULL;
- 474 t->state = 0;
- 475 atomic_set(&t->count, 0);
- 476 t->func = func;
- 477 t->data = data;
- 478 }
2)编写自己的tasklet处理程序
tasklet处理程序必须符合规定的函数类型:void tasklet_handler(unsigned long data)。因为是靠软中断实现,所以tasklet不能睡眠。这意味着你不能在tasklet中使用信号量或其他什么阻塞式函数。如果你的tasklet和其他的tasklet或软中断共享了数据,你必须进行适当的锁保护。
3)调度自己的tasklet
通过调用tasklet_schedule()函数来调度。在tasklet被调度以后在其还没有得到运行机会之前,如果一个相同的tasklet又被调度了,那么它仍只会运行一次。而如果这时它已经开始运行了,那么这个新的tasklet会被重新调度并再次运行。作为一种优化措施,一个tasklet总在调度它的处理器上执行-这是希望更好地利用处理器的高速缓存。可以调用tasklet_disable()函数来禁止某个指定的tasklet,也可以调用tasklet_enable()函数激活一个tasklet。还可以调用tasklet_kill()函数从挂起的队列中去掉一个tasklet。
3,ksoftirqd
每个处理器都有一个这样的线程,所有的线程名字都叫ksoftirqd/n,n对应于处理器的编号,这些线程是在最低的优先级上运行(nice值是19),这样好处是它们和其它重要的认为抢夺资源,在空闲的系统上,这个方案也表现良好。
4,工作队列和tasklet的区别~
工作队列运行在进程上下文中,可以中断,如果你的中断下半部分需要睡眠,那么应该使用工作队列的机制。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。