小任务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)假设不须要休 ...
随机推荐
- navicat for mysql怎么注册?navicat11全系列破解教程(附注册码)
来自脚本之家 http://www.jb51.net/softjc/473494.html
- HDUOJ-----1098 Ignatius's puzzle
Ignatius's puzzle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- Flask接通微信公众号
import hashlib import xml.etree.ElementTree as ET from flask import Flask, request import time app = ...
- 【JAVA】Exception in thread "main" java.lang.NoClassDefFoundError
java新手经常会遇到这个问题. 环境变量配置正确,eclipse下可以正常编译运行,命令行下可以使用javac生成.class文件,但是在当前目录运行的时候提示: 分析报错,可以发现系统从Pack文 ...
- cocos2dx 3.1从零学习(五)——动画
动画是游戏中最重要的表现部分,本篇仅仅是初步学习大部分动画的用法.没有什么原理性的东西,可是样例有非常多,假设有不熟的地方要练一下. 特别是Spawn和Sequence的组合使用,什么时候使用Spaw ...
- CPD轮播广告库的简单算法
在广告的领域中,有一种广告形式,采用的是CPD的售卖模式,为了对流量进行拆分,媒体方会对广告位进行轮播拆分.比如一个广告位,被拆成了10轮播,那么在广告主来预订广告位的时候,这个时候就可以告诉广告主, ...
- THINKPHP导入全部post参数
@extract($_POST);//导入全部POST参数直接使用变量
- %02x和%2x区别
%02x (x代表以十六进制形式输出,02代表不足两位,前面补0输出,如果超过两位,则以实际输出) 例: #include <stdio.h> #include <stdint.h ...
- Oracle PLSQL Demo - 04.数字FOR LOOP循环[NUMBERABLE (FOR) LOOP]
declare v_display ); begin .. loop .. loop dbms_output.put_line(i || ' - ' || j); end loop; end loop ...
- (基于Jenkins + SVN + Ant + Weblogic Server的)应用程序自动(/一键)部署的设想
一直想实现自动部署,这里说的自动部署,是指点击一个按钮(或定时执行),让计算机将最新的应用程序发布到相应的环境(UAT或PRD)中. 自动部署的意义 自动部署能省去繁琐的人工发布步骤:如配置得当,发布 ...