tasklet_hi_schedule分析

文件包含:

#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 data;

 };

其中:

字段next指向链表的下一个元素;

字段state定义了当前软中断的状态,是一个32位的无符号长整数,内核系统中只使用了bit1]和bit0]两个状态位。其中,bit1]=1表示当前tasklet正在执行,它仅对SMP系统才有意义,其作用就是为了防止多个CPU同时执行一个tasklet的情形出现;bit0]=1表示当前tasklet已经被调度,等待获得CPU资源执行。对这两个状态位的宏定义如下所示(interrupt.h):

enum

{

TASKLET_STATE_SCHED,    /* 软中断被调度,但未执行*/

TASKLET_STATE_RUN      /*软中断正在执行 */

};

字段count,是一个原子计数器,代表当前tasklet的引用计数值。只有当count等于0时,tasklet对应的中断处理函数才能被执行,也即此时tasklet是被使能的;如果count非零,则这个tasklet是被禁止的;

字段func,是一个函数指针,代表中断的处理函数;

字段data,代表中断处理函数执行时的参数,即字段func代表函数执行时的参数,是一个32位的无符号整数,其具体含义可由func字段指向的函数自行解释,比如将其解释成一个指向某个用户自定义数据结构的地址值等。    

返回参数说明:  

    此函数的返回值是void类型的变量,不返回任何值。 

实例解析:

编写测试文件:__tasklet_hi_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,tasklet1;

//自定义软中断处理函数,在此只是显示的作用

static void irq_tasklet_action(unsigned long data)

{

    /*显示当前软中断的状态*/

       printk("<0>in irq_tasklet_action the state of the tasklet is :%ld\n",(&tasklet)->state);

      printk("<0>tasklet running. by author\n");

     return;

} 

//自定义软中断处理函数,在此只是显示的作用

static void irq_tasklet_action1(unsigned long data)

{

    /*显示当前软中断的状态*/

       printk("<0>in irq_tasklet_action1 the state of the tasklet1 is :%ld\n",(&tasklet1)->state);

      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_action,data);

       tasklet_init(&tasklet1,irq_tasklet_action1,data);

       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分析 - delbert - 我的博客

如果将函数__tasklet_hi_schedule( )及上面的if( )条件判断都注释掉,替换成函数tasklet_schedule( ),重新编译模块,插入模块,输入命令dmesg –c出现如图5.4所示的结果:

__tasklet_hi_schedule分析 - delbert - 我的博客

结果分析:

由图5.3可以看出当中断处理函数被调度执行时,当前中断的状态值是2,可以判断当前state字段的bit[1]位是1,而bit[1]=1表示当前中断正在执行,二者相吻合5.35.4的唯一区别是两个中断处理函数被调度执行的顺序不同,在图5.3中经过函数__tasklet_hi_schedule( )处理的软中断,其被调度执行,此不是偶然,也非必然,但是大部分情况都是图5.3出现的情况,因为函数__tasklet_hi_schedule( )注册的软中断具有较高的优先级,能被调度处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值