文件包含:
#include<linux/interrupt.h>
函数定义:
在内核源码中的位置:linux-2.6.30/kernel/softirq.c
函数定义格式:void __tasklet_schedule(struct tasklet_struct *t)
函数功能描述:
函数__tasklet_schedule( )的主要作用是将参数t代表的软中断的描述符添加到向量tasklet_hi_vec的尾部,等待获得CPU资源,被调度执行。tasklet_hi_vec代表高优先级的软中断描述符链表。通过此函数添加的软中断具有较高的优先级,会先被调度处理。
输入参数说明:
函数输入参数是struct tasklet_struct结构体类型的指针,保存软中断的描述符信息,
其定义如下:
struct tasklet_struct
{
struct tasklet_struct *next;
unsigned long state;
atomic_t count;
void (*func)(unsigned long);
unsigned long da
};
其中:
字段next指向链表的下一个元素;
字段state定义了当前软中断的状态,是一个32位的无符号长整数,内核系统中只使用了bit[1]和bit[0]两个状态位。其中,bit[1]=1表示当前tasklet正在执行,它仅对SMP系统才有意义,其作用就是为了防止多个CPU同时执行一个tasklet的情形出现;bit[0]=1表示当前tasklet已经被调度,等待获得CPU资源执行。对这两个状态位的宏定义如下所示(interrupt.h):
enum
{
TASKLET_STATE_SCHED, /* 软中断被调度,但未执行*/
TASKLET_STATE_RUN /*软中断正在执行 */
};
字段count,是一个原子计数器,代表当前tasklet的引用计数值。只有当count等于0时,tasklet对应的中断处理函数才能被执行,也即此时tasklet是被使能的;如果count非零,则这个tasklet是被禁止的;
字段func,是一个函数指针,代表中断的处理函数;
字段da
返回参数说明:
此函数的返回值是void类型的变量,不返回任何值。
实例解析:
编写测试文件:__tasklet_hi_schedule.c
头文件引用及全局变量定义
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE(“GPL”);
static unsigned long da
static struct tasklet_struct tasklet,tasklet1;
//自定义软中断处理函数,在此只是显示的作用
static void irq_tasklet_act
{
/*显示当前软中断的状态*/
printk("<0>in irq_tasklet_act
printk("<0>tasklet running. by author\n");
return;
}
//自定义软中断处理函数,在此只是显示的作用
static void irq_tasklet_act
{
/*显示当前软中断的状态*/
printk("<0>in irq_tasklet_act
printk("<0>tasklet1 running. by author\n");
return;
}
static int __init __tasklet_hi_schedule_init(void)
{
printk("<0>into __tasklet_hi_schedule\n");
//申请两个软中断
tasklet_init(&tasklet,irq_tasklet_act
tasklet_init(&tasklet1,irq_tasklet_act
printk("<0>The state of the tasklet is :%ld\n",(&tasklet)->state); //显示当前中断的状态
printk("<0>The state of the tasklet1 is :%ld\n",(&tasklet1)->state);
tasklet_schedule(&tasklet); //把中断送入普通中断队列
if(!test_and_set_bit(TASKLET_STATE_SCHED, &tasklet1.state)) //测试并设置中断的状态
__tasklet_hi_schedule(&tasklet1); //把中断送入高优先级队列
//tasklet_schedule(&tasklet1);
tasklet_kill(&tasklet); //等待中断处理函数执行完毕,恢复调度之前的状态
tasklet_kill(&tasklet1);
printk("<0>out __tasklet_hi_schedule\n");
return 0;
}
static void __exit __tasklet_hi_schedule_exit(void)
{
printk("<0>Goodbye __tasklet_hi_schedule\n");
return;
}
module_init(__tasklet_hi_schedule_init);
module_exit(__tasklet_hi_schedule_exit);
实例结果及分析:
执行命令insmod __tasklet_hi_schedule.ko加载模块,然后输入命令dmesg –c查看内核输出信息,出现如图5.3所示的结果:
如果将函数__tasklet_hi_schedule( )及上面的if( )条件判断都注释掉,替换成函数tasklet_schedule( ),重新编译模块,插入模块,输入命令dmesg –c出现如图5.4所示的结果:
结果分析:
由图5.3可以看出当中断处理函数被调度执行时,当前中断的状态值是2,可以判断当前state字段的bit[1]位是1,而bit[1]=1表示当前中断正在执行,二者相吻合。图5.3和5.4的唯一区别是两个中断处理函数被调度执行的顺序不同,在图5.3中经过函数__tasklet_hi_schedule( )处理的软中断,其先被调度执行,此不是偶然,也非必然,但是大部分情况都是图5.3出现的情况,因为函数__tasklet_hi_schedule( )注册的软中断具有较高的优先级,能先被调度处理。