7.2 下半部和推后执行的工作_tasklet

来源:互联网 发布:p2p网络金融 编辑:程序博客网 时间:2024/06/04 20:45

7.3.1 tasklet的实现

    因为tasklet是通过软中断实现的,所以它们本身也是软中断。tasklet由两类软中断代表:HI_SOFTIRQ和TASKLET_SOFTIRQ。这两者之间唯一的实际区别在于HI_SOFTIRQ类型的软中断先于TASKLET_SOFTIRQ类型的软中断执行。

 

1. tasklet结构体

    tasklet有tasklet_struct结构表示。每个结构体单独代表一个tasklet,它在<linux/interrupt.h>中定义。

 

2. 调度tasklet

    已调度的tasklet(等同于被触发的软中断)存放在两个单处理器数据结构:tasklet_vec(普通tasklet)和tasklet_hi_vec(高优先级的tasklet)中。这两个数据结构都是有tasklet_struct结构体构成的链表。

    tasklet由tasklet_schedule()和tasklet_hi_schedule()函数进行调度,它们接受一个指向tasklet_struct结构体指针作为参数。

    而这两个处理程序,tasklet_action()和tasklet_hi_action(),就是tasklet处理的核心。

    所有的tasklet都通过重复运用HI_SOFTIRQ和TASKLET_SOFTIRQ这两个软中断来实现。

 

7.3.2 使用tasklet

1. 声明你自己的tasklet

    可以静态地创建tasklet,也可以动态地创建它。选择哪种方式取决于到底是有(或者是想要)一个对tasklet的直接引用还是间接引用。如果准备静态地创建一个tasklet(也就是有一个它的直接引用),使用下面<linux/interrupt.h>中定义的两个宏中的一个:

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

    还可以通过讲一个间接引用(一个指针)赋给一个动态创建的tasklet_struct结构的方式来初始化一个tasklet:

  • tasklet_init(t, tasklet_handler, dev);

 

2. 编写你自己的tasklet处理程序

    因为是靠软中断实现,所以tasklet不能睡眠。这意味着不能在tasklet中使用信号量或者其他什么阻塞式的函数。两个相同的tasklet绝不会同时执行,这点和软中断不同--尽管两个不同的tasklet可以在两个处理器上同时执行。如果tasklet和其他的tasklet或者是软中断共享了数据,必须进行适当的锁保护。

 

3. 调度你自己的tasklet

    通过调用tasklet_shcedule()函数并传递给它相应tasklet_struct的指针,该tasklet就会被调度以便执行。

    可以调用tasklet_disable()函数来禁止某个指定的tasklet。如果该tasklet当前正在执行,这个函数会等到它执行完毕再返回。也可以调用tasklet_disable_nosync()函数,它也可用来禁止指定的tasklet,不过它无须在返回前等待tasklet执行完毕。这么做往往不太安全,因为无法估计该tasklet时候仍在执行。调用tasklet_enable()函数可以激活一个tasklet,如果希望激活DECLARE_TASKLET_DISABLED()创建的tasklet,也得调用这个函数。

    可以通过调用tasklet_kill()函数从挂起的队列中去掉一个tasklet。这个函数首先等待该tasklet执行完毕,然后再将它移去。由于该函数可能引起休眠,所以禁止在中断上下文中使用它。

 

7.3.3 ksoftirqd

 

7.3.4 老的BH机制

原创粉丝点击