__tasklet_schedule函数功能描述:函数__tasklet_schedule( )用于将一个tasklet_struct结构体代表的软中断添加到tasklet_vec队列的尾部,并等待获取CPU资源,被调度执行。tasklet_vec是一个保存软中断的链表,与链表tasklet_hi_vec中保存的软中断相比,其保存的软中断优先级较低。
__tasklet_schedule文件包含
#include<linux/interrupt.h>
__tasklet_schedule函数定义
在内核源码中的位置:linux-3.19.3/kernel/softirq.c
函数定义格式:
void __tasklet_schedule(struct tasklet_struct *t)
__tasklet_schedule输入参数说明
此函数的输入参数是struct tasklet_struct结构体类型的指针,代表将添加入内核系统的软中断,保存软中断的信息,其定义及详细信息参考函数__tasklet_hi_schedule( )分析文档的输入参数说明部分。
__tasklet_schedule返回参数说明
此函数的返回值是void类型的变量,即函数不返回任何值。
__tasklet_schedule实例解析
编写测试文件:__tasklet_schedule.c
头文件引用及全局变量声明:
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
static unsigned long data=0;
static struct tasklet_struct tasklet;
中断处理函数定义:
// 自定义软中断处理函数,在此只有显示功能
static void irq_tasklet_action(unsigned long data)
{
/*显示当前中断的状态*/
printk("in the irq_tasklet_action the state of the tasklet is :%ld\n", (&tasklet)->state);
printk("tasklet running. by author\n");
return;
}
模块初始化函数,验证函数的调用:
static int __init __tasklet_schedule_init(void)
{
printk("into __tasklet_schedule\n");
/*初始化一个struct tasklet_struct变量,即申请一个软中断变量*/
tasklet_init(&tasklet, irq_tasklet_action, data);
printk("the state of the tasklet after tasklet_init is :%ld\n", (&tasklet)->state);
//显示软中断状态
if (! test_and_set_bit(TASKLET_STATE_SCHED, &tasklet.state))
//测试及设置软中断的状态
__tasklet_schedule(&tasklet); //将中断变量放入软中断执行队列
printk("the state of the tasklet after __tasklet_schedule is :%ld\n", (&tasklet)
->state); //显示中断状态
printk("out __tasklet_schedule_init\n");
return 0;
}
模块退出函数:
static void __exit __tasklet_schedule_exit(void)
{
printk("Goodbye __tasklet_schedule\n");
return;
}
模块加载、退出函数的调用:
module_init(__tasklet_schedule_init);
module_exit(__tasklet_schedule_exit);
实例运行结果及分析:
编译模块,执行命令insmod __tasklet_schedule.ko插入内核模块,然后输入命令dmesg -c查看内核输出信息,出现如图所示结果。
结果分析:
由图可以看出函数tasklet_init( )执行之后当前tasklet的状态值为0,函数__tasklet_schedule( )执行之后,当前tasklet的状态值为1。此结果不是函数__tasklet_schedule( )的作用,而是函数test_and_set_bit( )的作用,此设置是必要的,因为函数__tasklet_schedule( )的作用是调度当前软中断,所以状态值也要变化,作者试验过,如果不设置,会出现错误。由图中输出信息可以看出,软中断对应的中断处理函数被调度执行,说明函数__tasklet_schedule( )能够将软中断加入tasklet_vec链表中,如果没有函数__tasklet_schedule( ),软中断对应的中断处理函数是不会被调度执行的。