关于中断的buttom half (二)

Tasklets

 tasklets建立在软中断上的一种机制,它是一种软中断,但又与软中断不同,它有自己的特点:

1,可以动态创建和销毁。

2,在运行时,多次进行调度,此时也只能运行一次,并且调度时总是会让其在同一处理器上运行,如此可以很好的利用cache。

 像进程一样,tasklet也由一个结构体来表示:

 struct tasklet_struct
 {
        struct tasklet_struct *next;  //链表上的下一个tasklets
        unsigned long state;                 //tasklets的状态
        atomic_t count;       //引用数,表示这个tasklets是否被disable
        void (*func)(unsigned long);  //处理函数
        unsigned long data;    //处理函数的参数
 };

   tasklet的状态如下:

 enum
 {
        TASKLET_STATE_SCHED,    /* Tasklet is scheduled for execution */ //相当于进程状态中的就绪状态,可以被调度运行
        TASKLET_STATE_RUN       /* Tasklet is running (SMP only) */  //表示当前是否正处于运行状态
 };

 tasklet有两种形式的存在,一种是普通的tasklet,另一种是高优先级的tasklet,它们对应了两个软中断,分别为:TASKLET_SOFTIRQ

和HI_SOFTIRQ

   在内核中定义如下:

 static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec);
 static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec);

 这是两个双向链表,当某种类型的tasklet将被调度时,会把其挂到对应的链表下。

   tasklet调度过程:

 void __tasklet_schedule(struct tasklet_struct *t)
 {
        unsigned long flags;

        local_irq_save(flags);  //Disable本cpu的中断,并保存中断状态
        t->next = NULL;

        *__this_cpu_read(tasklet_vec.tail) = t; //把需要调度的tasklet加入到链表
        __this_cpu_write(tasklet_vec.tail, &(t->next));


        raise_softirq_irqoff(TASKLET_SOFTIRQ); //调度对应的软中断
        local_irq_restore(flags);  //Enable本cpu的中断,并恢复中断状态
 }
 如上函数对应的是普通tasklet,还有一个对应提高优先级的tasklets(__tasklet_hi_schedule),调用过程相似,只是需要触发HI_SOFTIRQ软中断。

 静态定义tasklet

    DECLARE_TASKLET(name, func, data)
    DECLARE_TASKLET_DISABLED(name, func, data);

    动态定义tasklet

    void tasklet_init(struct tasklet_struct *t,void (*func)(unsigned long), unsigned long data)

    调度tasklet

    void tasklet_schedule(struct tasklet_struct *t)

    使能/禁用tasklet

    void tasklet_enable(struct tasklet_struct *t)

    void tasklet_disable(struct tasklet_struct *t)

    void tasklet_disable_nosync(struct tasklet_struct *t)

     tasklet_disable和tasklet_disable_nosync区别是如果此时tasklet正在运行,要等到运行结束tasklet_disable才能返回,tasklet_disable_nosync

则不用等待就可返回,它们的区别和中断中的两个接口(disable_irq/disable_irq_nosync)相似。

    移除tasklet

    void tasklet_kill(struct tasklet_struct *t) //等待tasklet运行结束,然后把tasklet从调度队列中移除。

 注意:

 tasklet_disable和tasklet_kill可能在调用时都需要等待,所以在中断处理函数中不能调用。



   




 

 
  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值