Chinaunix首页 | 论坛 | 博客

分类: LINUX

2011-09-19 21:13:11

  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;
......
}
阅读(1411) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~