小任务tasklet应用
一个使用tasklet的中断程序首先会通过执行中断处理程序来快速完成上半部分的工作,接着通过调度tasklet使得下半部分的工作得以完成,但是下半部分何时执行属于内核的工作。
由于tasklet依靠软中断实现,所以tasklet不能休眠。这就意味着不能在tasklet中使用信号量或其他任何可能引起阻塞的函数。两个相同的tasklet绝不会同时执行。这点是和软中断的一个重要的区别。尽管两个不同的tasklet可以在两个处理器上同时执行,但只要不同的tasklet不共享数据,就不会有任何问题。当然,如果要共享数据,仍然需要使用本地锁保护临界区数据。
本文档描述基于3.14.77内核。
1. 定义
tasklet定义在linux/interrupt.h中,实现在kernel/softirq.c中。
struct tasklet_struct {
struct tasklet_struct *next;
unsigned long state;
atomic_t count;
void (*func)(unsigned long);
unsigned long data; // 给tasklet处理函数传递的参数
};
tasklet_struct.state可以设置成0,也可以设置成两个枚举值(TASKLET_STATE_SCHED和TASKLET_STATE_RUN),除此之外,tasklet_struct.state不能设置成其他的值。
enum
{
TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution */
TASKLET_STATE_RUN /* Tasklet is running (SMP only) */
};
tasklet_struct.count是tasklet的引用计数器,如果count不为0,表示tasklet被禁用,不允许执行。只有当count为0时,tasklet才会被激活,并且只有tasklet被设置为挂起时,该tasklet才能被执行(下一次调用do_softirq函数时会执行所有挂起的tasklet)。
初始化
#define DECLARE_TASKLET(name, func, data) \
struct tasklet_struct name = { NULL, , ATOMIC_INIT(), func, data } #define DECLARE_TASKLET_DISABLED(name, func, data) \
struct tasklet_struct name = { NULL, , ATOMIC_INIT(), func, data } void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data);
由于tasklet_init函数本身不会创建tasklet_struct结构体,因此,在调用tasklet_init函数之前,需要使用kmalloc或其他类似的内核空间分配函数为tasklet_struct结构体分配内存空间(动态创建tasklet_struct结构体)。
调度
tasklet_schedule(&mytasklet); //调用底半部,注意,这不是立即调用,是调度,意味着tasklet底半部会在顶半部执行完成后才会执行。
在_tasklet_schedule函数中调用raise_softirq_irqoff函数挂起了TASKLET_SOFTIRQ中断。这就意味着一旦do_softirq函数在某个时刻被调用,系统就会扫描软中断向量表(softirq_vec),这时发现TASKLET_SOFTIRQ软中断被挂起,就会立刻执行与TASKLET_SOFTIRQ软中断对应的处理程序。在TASKLET_SOFTIRQ软中断处理程序中会扫描tasklet向量表(tasklet_vec)。
销毁
一般会在Linux驱动的exit函数中使用tasklet_kill函数(kernel/softirq.c)销毁当前的tasklet,实际上就是将tasklet_struct.state设为0。
extern void tasklet_kill(struct tasklet_struct *t);
extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu);
2. 应用
static struct tasklet_struct my_tasklet; static void tasklet_handler (unsigned long data)
{
printk(KERN_ALERT "tasklet_handler is running.\n");
} tasklet_init(&my_tasklet, tasklet_handler, ); // 初始化tasklet
tasklet_schedule(&my_tasklet); // 调度tasklet处理程序 tasklet_kill(&my_tasklet);
3. 小结
由于软中断是Linux系统全局的,整个Linux系统最多也只能有10个不同类型的软中断。而且如果不修改Linux内核源代码,这个最大中断数是不会变的,就算修改了内核源代码,最大也只能有32个软中断。为了可以处理更多的底半部,系统定义了两个特殊的软中断(HI_SOFTIRQ和TASKLET_SOFTIRQ),通过这两个软中断的处理函数可以执行两个tasklet向量(tasklet_vec和tasklet_hi_vec)中的tasklet处理程序。因此tasklet处理程序的执行效率要比软中断处理程序的执行效率低一些(也低不了太多)。这是因为tasklet处理程序需要先执行软中断处理程序,然后才能扫描tasklet向量,比软中断处理程序多了一步。
参考:
3. tasklet
小任务tasklet应用的更多相关文章
- Linux软中断、tasklet和工作队列
Linux内核中的软中断.tasklet和工作队列详解 引言 软中断.tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的“下半部”(bottom half)演变而来 ...
- linux中的tasklet机制【转】
转自:http://blog.csdn.net/yasin_lee/article/details/12999099 转自: http://www.kerneltravel.net/?p=143 中断 ...
- Linux tasklet 和workqueue学习
中断服务程序一般都是在中断请求关闭的条件下执行的,以避免嵌套而使中断控制复杂化.但是,中断是一个随机事件,它随时会到来,如果关中断的时间太长,CPU就不能及时响应其他的中断请求,从而造成中断的丢失.因 ...
- linux 中断softirq tasklet
硬中断为什么不能休眠--- 中断线程以及软中断解决了什么问题---- 软中断cb函数是否允许相应本地中断,什么时候开启中断关闭中断---- 什么是软中断上下文------- 什么是tasklet 和软 ...
- linux中断编程
本文档只介绍中断编程所需的函数及应用,中断完整处理流程应参考文档<linux中断处理流程>,可参考文档<linux内核对中断的处理方式>对中断初步了解. 本文档基于3.14内核 ...
- Linux 中断下半部
为什么使用中断下半部? 中断执行的原则是要以最快的速度执行完,而且期间不能延时和休眠! 可是现实中,中断中可能没办法很快的处理完需要做的事,或者必须用到延时和休眠,因此引入了中断下半部. 中断中处理紧 ...
- 内核源码分析之tasklet(基于3.16-rc4)
tasklet是在HI_SOFTIRQ和TASKLET_SOFTIRQ两个软中断的基础上实现的(它们是在同一个源文件中实现,由此可见它们的关系密切程度),它的数据结构和软中断比较相似,这篇博文将分析t ...
- 中断下半部-tasklet
http://edsionte.com/techblog/ tasklet的实现 tasklet(小任务)机制是中断处理下半部分最常用的一种方法,其使用也是非常简单的.正如在前文中你所知道的那样,一个 ...
- tasklet和workqueue的选择
linux内核设计与实现page127中有个比較,内容比較多.概括一下就是1. tasklet不能休眠, 2. 不须要休眠tasklet效率更高 3.有休眠仅仅能workqueue (1)假设不须要休 ...
随机推荐
- 【转载】spring mvc 使用session
http://home.51.com/gaoyangboy/diary/item/10036382.html Spring2.5 访问 Session 属性的四种策略 Posted on 2008-1 ...
- 【转载】@RequestMapping的分类
@RequestMapping的分类 类级别的和方法级别的@RequestMapping的几种形式: @RequestMapping(method = RequestMethod.GET) @Req ...
- 用zd1211+Ubuntu 10.04实现的AP
[日期:2010-06-24] zd1211 在Ubuntu 10.04 LTS上的master mode 的问题解决之后,理论上就可以把zd1211 USB网卡用来做一个AP了,实际上还有几个问 ...
- HDUOJ------2492Ping pong
Ping pong Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- window.postMessage实现网页间通信
window.postMessage() 方法可以安全地实现跨域通信.通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以 ...
- 直线的中点Bresenham算法的实现
一.实验目的 1.掌握在MFC中搭建图形绘制的基本框架的方法: 2.将直线的中点Bresenham算法转化成可执行代码. 二.实验内容 1. 通过分析具体数据在中点Bresenham算法上的执行过程, ...
- sqoop安装遇到的问题
错误: 找不到或无法加载主类 org.apache.sqoop.Sqoop最终解决办法是吧sqoop目录下的sqoop-1.4.4.jar拷贝到hadoop的lib目录下解决 Warning: /us ...
- 网站博客更换主机空间搬家:Discuz! X2.5老鹰主机搬家全过程
http://www.freehao123.com/discuz-x2-5-banjia/由于我放在hawkhost老鹰主机主机的部落论坛就要到期了,而老鹰主机的续费价格却是按照原价来的,没有任何优惠 ...
- ubuntu(14.04版本) 配置虚拟环境(一个ip对应多个域名)
以下操作是建立在apahce安装成功的情况下 1.配置本地的host. 假设虚拟主机上的ip是:192.168.1.51,那么客户端本地的host可以配置成:
- vsftp添加用户及测试
上一篇我们讲了vsftp安装以及配置,这篇我们讲下如何添加用户,然后我们测试一下,看看是否成功. 首先说下添加用户,如图执行命令即可: 这里简单解释一下:第一条命令是添加用户,第二条命令是设置用户密码 ...