多数情况下,为了控制一个寻常的硬件设备,tasklet机制都是实现自己下半部的最佳选择;tasklet可以动态创建,使用方便,执行起来还算快;

声明tasklet

tasklet既可以静态的创建,也可以动态的创建;如果准备静态的创建一个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 }

两个宏都能根据给定的名称静态的创建一个tasklet_struct结构;当该tasklet被调度以后,给定函数func会被执行,它的参数是data;前面一个宏创建的tasklet的引用计数设置为0,该tasklet处于激活状态;另一个宏引用计数为1,该tasklet处于禁止状态;

tasklet处理程序

tasklet处理程序必须符合以下定义:

 void tasklet_handler(ungigned long data)

因为靠软中断实现,所以tasklet不能睡眠;这意味着你不能再tasklet中使用信号量或者其他阻塞式的函数;由于tasklet运行时允许响应中断,所以必须做好预防工作,如果你的tasklet和中断处理程序之间共享了某些数据的话;两个相同的tasklet绝不会同时执行,这点和软中断不同,尽管两个不同的tasklet可以再两个处理器上同时执行;如果tasklet和其他的tasklet或者软中断共享了数据,就必须进行锁保护;

调度tasklet

通过调用tasklet_schedule()函数并传递给它们相应的tasklet_struct指针,该tasklet就会被调度以便执行;

 void tasklet_schedule(struct tasklet_struct *t)

在tasklet被调度以后,只要有机会它就会尽可能早的运行。在它还没有得到运行机会之前,如果有一个相同的tasklet又被调度了,那么它只会运行一次;如果这时它已经开始运行了,比如说在另外一个处理器上,那么这个新的tasklet会被调度并再次运行;作为一种优化措施,一个tasklet总在调度它的处理器上执行–这是希望能更好的利用处理器的高速缓存;

禁用启用tasklet

tasklet_disable()用来禁止某个指定的tasklet,如果该tasklet当前正在执行,这个函数会等到它执行完毕再返回;还可以调用tasklet_disable_nosync(),它也用来禁止指定的tasklet,不过它无需等待tasklet执行完毕,这么做通常不安全,因为无法估计tasklet是否仍在执行;调用tasklet_enable()可以激活一个tasklet,如果希望激活DECLARE_TASKLET_DISABLED()宏创建的tasklet,也需要调用这个函数;

 void tasklet_disable_nosync(struct tasklet_struct *t)
void tasklet_disable(struct tasklet_struct *t) void tasklet_enable(struct tasklet_struct *t)
删除挂起tasklet

可以通过调用tasklet_kill()从挂起的队列中去掉一个tasklet,该函数的参数一个指向某个tasklet的tasklet_struct指针;在处理一个经常重新调度它自身的tasklet的时候,从挂起的队列中移除已调度的tasklet很有用;这个函数首先等待tasklet执行完毕,然后再将它移除;当然,没什么方法可以阻止其他地方的代码重新调度该tasklet;由于该函数可能引起休眠,所以禁止在中断上下文中使用;

 void tasklet_kill(struct tasklet_struct *t)
ksoftirq

每个处理器都有一组辅助处理软中断(和tasklet)的内核线程;当内核中出现大量的软中断的时候,这些内核线程就会辅助处理它们;

每个处理器都有一个处理线程,名字叫做ksoftirqd/n,区别在于n,它对应着处理器的编号;在一个双处理器上就有两个这样的线程,分别叫ksoftirq/0和ksoftirq/1;为了保证只要有空闲的处理器,就会处理软中断,所以每个处理器都会分配一个这样的线程;一旦初始化,就会执行死循环处理中断;只要有待处理的中断,ksoftirq就会调度do_softirq()去处理它们;当所有中断处理完成之后,内核线程将自己设置为TASK_INTERRUPTIBLE状态,以唤起调度程序选择其他可执行线程投入运行;

Linux设备驱动程序 之 tasklet的更多相关文章

  1. linux设备驱动程序该添加哪些头文件以及驱动常用头文件介绍(转)

    原文链接:http://blog.chinaunix.net/uid-22609852-id-3506475.html 驱动常用头文件介绍 #include <linux/***.h> 是 ...

  2. 【转】linux设备驱动程序中的阻塞机制

    原文网址:http://www.cnblogs.com/geneil/archive/2011/12/04/2275272.html 阻塞与非阻塞是设备访问的两种方式.在写阻塞与非阻塞的驱动程序时,经 ...

  3. Linux设备驱动程序 第三版 读书笔记(一)

    Linux设备驱动程序 第三版 读书笔记(一) Bob Zhang 2017.08.25 编写基本的Hello World模块 #include <linux/init.h> #inclu ...

  4. Linux设备驱动程序学习之分配内存

    内核为设备驱动提供了一个统一的内存管理接口,所以模块无需涉及分段和分页等问题. 我已经在第一个scull模块中使用了 kmalloc 和 kfree 来分配和释放内存空间. kmalloc 函数内幕 ...

  5. 教你写Linux设备驱动程序:一个简短的教程

    教你写Linux设备驱动程序:一个简短的教程 http://blog.chinaunix.net/uid-20799298-id-99675.html

  6. linux设备驱动程序_hello word 模块编译各种问题集锦

    在看楼经典书籍<linux设备驱动程序>后,第一个程序就是编写一个hello word 模块. 原以为非常easy,真正弄起来,发现问题不少啊.前两天编过一次,因为没有记录,今天看的时候又 ...

  7. Linux设备驱动程序学习----1.设备驱动程序简介

    设备驱动程序简介 更多内容请参考Linux设备驱动程序学习----目录 1. 简介   Linux系统的优点是,系统内部实现细节对所有人都是公开的.Linux内核由大量复杂的代码组成,设备驱动程序可以 ...

  8. Linux设备驱动程序学习----2.内核模块与应用程序的对比

    内核模块与应用程序的对比 更多内容请参考Linux设备驱动程序学习----目录 1. 内核模块与应用程序的对比 内核模块和应用程序之间的不同之处: 大多数中小规模的应用程序是从头到尾执行单个任务,而模 ...

  9. Linux设备驱动程序学习----3.模块的编译和装载

    模块的编译和装载 更多内容请参考Linux设备驱动程序学习----目录 1. 设置测试系统 第1步,要先从kernel.org的镜像网站上获取一个主线内核,并安装到自己的系统中,因为学习驱动程序的编写 ...

随机推荐

  1. JVM内存结构划分

    JVM内存结构划分 JVM内存结构划分 数据区域划分 程序计数器 虚拟机栈 本地方法栈 堆 方法区 运行时常量池 StringTable 直接内存 创建新对象说明 对象的创建 对象的内存布局 对象头 ...

  2. win10下PLSQL Developer 连接ubuntu上安装的oracle 11g

    说明:过程记录的不是很相信,只记录基本步骤.并不适合想一步一步照做的同学. win10下需要的操作 1.微软官网下载instantclient,然后接到到本地一个文件夹,注意路径不要又空格,中文和括号 ...

  3. 一组简单好看的css3渐变按钮

    主要代码如下: body { background:#fff } /* Mixins */ /* bg shortcodes */ .bg-gradient1 span,.bg-gradient1:b ...

  4. c# 类成员的可访问性

  5. centos7下安装zookeeper&zookeeper集群的搭建

    一.centos7下安装zookeeper 1.zookeeper 下载地址 https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/ 2.安装步骤 ...

  6. Js调用本地exe的方式

    1.     使用记事本(或其他文本编辑器)创建一个myprotocal.reg文件,并写入以下内容 Windows Registry Editor Version 5.00 [HKEY_CLASSE ...

  7. python-----将图片与标注的xml坐标水平翻转

    我们做机器学习的时候,总会用到很多训练集,然后我们的数据比较少的时候,就可以将图片翻转标注.代码如下: #!/usr/bin/env python # -*- coding: utf-8 -*- # ...

  8. java学习笔记15-封装

    把属性(成员变量)设置为私有(private),把方法设置为共有的(public),假如外界想要得到或者改变某个属性,只能通过方法来办到,这其实是封装的思想之一. 新建一个Student类,这个类有几 ...

  9. 【产品对比】Word开发工具Aspose.Words和Spire.Doc性能和优劣对比一览

    转:evget.com/article/2018/4/3/27885.html 概述:Microsoft Office Word是微软公司的一个文字处理器应用程序,作为办公软件必不可少的神器之一,Wo ...

  10. Linux卸载Django

    cd /usr/lib/python2.7/dist-packages sudo rm -rf django sudo rm Django-1.8.7.egg-info 基本命令如此,具体文件因版本有 ...