首页 > 人文 > >
Linux内核中的软中断、tasklet和工作队列详解( 四 )
2026-08-05
struct tasklet_struct{struct tasklet_struct *next;//将多个tasklet链接成单向循环链表unsigned long state;//TASKLET_STATE_SCHED(Tasklet is scheduled for execution)TASKLET_STATE_RUN(Tasklet is running (SMP only))atomic_t count;//0:激活tasklet 非0:禁用taskletvoid (*func)(unsigned long); //用户自定义函数unsigned long data;//函数入参};static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec);//低优先级static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec);//高优先级相关API
#define DECLARE_TASKLET(name, func, data) \struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data }//定义名字为name的非激活tasklet#define DECLARE_TASKLET_DISABLED(name, func, data) \struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(1), func, data } //定义名字为name的激活taskletvoid tasklet_init(struct tasklet_struct *t,void (*func)(unsigned long), unsigned long data)//动态初始化taskletstatic inline void tasklet_disable(struct tasklet_struct *t)//函数暂时禁止给定的tasklet被tasklet_schedule调度 , 直到这个tasklet被再次被enable;若这个tasklet当前在运行, 这个函数忙等待直到这个tasklet退出static inline void tasklet_enable(struct tasklet_struct *t)//使能一个之前被disable的tasklet;若这个tasklet已经被调度, 它会很快运行 。 tasklet_enable和tasklet_disable必须匹配调用, 因为内核跟踪每个tasklet的"禁止次数"static inline void tasklet_schedule(struct tasklet_struct *t)//调度 tasklet 执行 , 如果tasklet在运行中被调度, 它在完成后会再次运行; 这保证了在其他事件被处理当中发生的事件受到应有的注意. 这个做法也允许一个 tasklet 重新调度它自己tasklet_hi_schedule(struct tasklet_struct *t)//和tasklet_schedule类似 , 只是在更高优先级执行 。 当软中断处理运行时, 它处理高优先级 tasklet 在其他软中断之前 , 只有具有低响应周期要求的驱动才应使用这个函数, 可避免其他软件中断处理引入的附加周期.tasklet_kill(struct tasklet_struct *t)//确保了 tasklet 不会被再次调度来运行 , 通常当一个设备正被关闭或者模块卸载时被调用 。 如果 tasklet 正在运行, 这个函数等待直到它执行完毕 。 若 tasklet 重新调度它自己 , 则必须阻止在调用 tasklet_kill 前它重新调度它自己 , 如同使用 del_timer_sync 实现原理
static inline void tasklet_schedule(struct tasklet_struct *t){if (!test_and_set_bit(TASKLET_STATE_SCHED, }void __tasklet_schedule(struct tasklet_struct *t){unsigned long flags;local_irq_save(flags);t->next = NULL;*__get_cpu_var(tasklet_vec).tail = t;__get_cpu_var(tasklet_vec).tail = //加入低优先级列表raise_softirq_irqoff(TASKLET_SOFTIRQ);//触发软中断local_irq_restore(flags);}tasklet执行过程 TASKLET_SOFTIRQ对应执行函数为tasklet_action , HI_SOFTIRQ为tasklet_hi_action , 以tasklet_action为例说明 , tasklet_hi_action大同小异 。 static void tasklet_action(struct softirq_action *a){struct tasklet_struct *list;local_irq_disable();list = __get_cpu_var(tasklet_vec).head;__get_cpu_var(tasklet_vec).head = NULL;__get_cpu_var(tasklet_vec).tail = //取得tasklet链表local_irq_enable();while (list) {struct tasklet_struct *t = list;list = list->next;if (tasklet_trylock(t)) {if (!atomic_read(t->func(t->data);tasklet_unlock(t);continue;}tasklet_unlock(t);}//如果t->count的值不等于0 , 说明这个tasklet在调度之后 , 被disable掉了 , 所以会将tasklet结构体重新放回到tasklet_vec链表 , 并重新调度TASKLET_SOFTIRQ软中断 , 在之后enable这个tasklet之后重新再执行它local_irq_disable();t->next = NULL;*__get_cpu_var(tasklet_vec).tail = t;__get_cpu_var(tasklet_vec).tail =__raise_softirq_irqoff(TASKLET_SOFTIRQ);local_irq_enable();}}
推荐阅读
[连衣裙]周润发前妻余安安太惊艳了,穿碎花连衣裙配短发,哪敢相信61岁
白酒|曝i茅台APP申购成功无法付款 眼睁睁看着到手茅台飞了
#梦幻西游#梦幻西游:经验不够,箱子来凑?结果,玩家却有意外收获!
##为什么日本房子都不铺瓷砖?内行人说出实情,真后悔察觉太晚了
小小谈健康既养眼又养生,你想在家中的阳台上种点啥?种点草药吧
体坛小说|双姜再发威,CBA最强黑马诞生!吉林轰18分大胜北控获6连胜
业态|前三季度文化企业营业收入降幅收窄 文化新业态发展势头强劲
阿里巴巴|得分率92.3%!阿里云计算能力全球第1,亚马逊、微软、谷歌随后?
4G@4G版iPhone12起售价4198,留给国产手机的时间不多了!
中国青年网|安倍成为日本连续执政时间最长首相,2799天
小池百合子再次当选日本东京都知事 领导能力将受考验
冒汗|酸香爽口、出锅抢着吃,大冬天,家人也能吃得鼻尖冒汗,真爽快!
胡八一:奇异博士穿上钢铁侠战甲并非概念,漫威终于公布了当时的拍摄场景
#安兔兔#一加8系列官宣:2K/120Hz屏/骁龙865