Tasklet机制是特殊的软中断。在linux源代码情景中,作者列出了两中中断方式。一个是BH,一个是Tasklet.
某中程度上,Tasklet是linux内核对bh的一种扩展。在linux2.4内核中引入了softirq之后,原有的bh机制通过tasklet纳入到softirq机制。
tasklet与softirq机制的不同点。
一、tasklet机制某一段tasklet代码在某一时刻只能在一个cpu上运行;不同的tasklet代码可以在不同的cpu上并发。
static void tasklet_action(struct softirq_action *a)
{
int cpu = smp_processor_id(); /*获取cpuid;
struct tasklet_struct *list;
local_irq_disable();
tasklet_vec[cpu].list;
local_irq_enable(); /*禁止本地cpu中断*/
while(list != NULL) {/**/
struct tasklet_struct *t = list;
list = list->next;
if (tasklet_trylock(t)){
if (atomic_read(&t->count) == 0){
clear_bit(TASKLET_STATE_SCHED, &t->state);
t->func(t->data); /*执行*/
#ifdef CONFIG_SMP
smp_mb__before_clear_bit();
#endif
tasklet_unlock(t);
continue;
}
tasklet_unlock(t);
}
local_irq_disable();
t->next = tasklet_cec[cpu].list;
tasklet_vec[cpu].list =t;
cpu_raise_softirq(cpu, TASKLET_SOFTIRQ);/*这是使软中断开启*/
local_irq_enable();
}
}
而do_softirq(){
.....
if(in_interrupt())/*#define in_interrput()({int __cpu = smp_processor_id(); \
// (local_irq_count(__cpu) + local_bh_count(__cpu) ! = 0);})
//看有无本地中断或者软中断正在运行,如果有,返回。
return;
active = softirq_active(cpu) & mask;/*两个int类型为同一位都是1,其余都是0的数*/
......
h = softirq_vec;/*一个32位数组全局变量,类似于中断机制中irq_desc[].是softirq_action结构类型。
do{
if(active & 1)/*此时将数组内的都为active标志位的,执行*/
h->action(h);/*调用
h++;
active >>= 1;/*移位*/
}while(active);
do_softirq()->bh_action()
static void bh_action(unsigned long nr)
{
int cpu = smp_processor_id();
if (!spin_trylock(&global_bh_lock))/*全局变量global_bh_lock;别的cpu不能进入此区间。所以只能有一个cpu运行。
goto resched;
if(!hardirq_trylock(cpu))//#define hardirq_trylock(cpu) (local_irq_count(cpu) == 0)防止硬件终端*/
goto resched_unlock;
......
}
阅读(1458) | 评论(0) | 转发(0) |