未加星标

tasklet机制和工作队列

字体大小 | |
[系统(linux) 所属分类 系统(linux) | 发布者 店小二04 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏
1. Tasklet 机制分析 上面我们介绍了软中断机制, linux 内核为什么还要引入 tasklet 机制呢?主要原因是软中断的 pending 标志位也就 32 位,一般情况是不随意增加软中断处理的。而且内核也没有提供通用的增加软中断的接口。其次内,软中断处理函数要求可重入,需要考虑到竞争条件比较多,要求比较高的编程技巧。所以内核提供了 tasklet 这样的一种通用的机制。 其实每次写总结的文章,总是想把细节的东西说明白,所以越写越多。这样做的好处是能真正理解其中的机制。但是,内容太多的一个坏处就是难道记忆,所以,在讲清楚讲详细的同时,我还要把精髓总结出来。 Tasklet 的特点,也是 tasklet 的精髓就是: tasklet 不能休眠,同一个 tasklet 不能在两个 CPU 上同时运行,但是不同 tasklet 可能在不同 CPU 上同时运行,则需要注意共享数据的保护。 主要的数据结构 static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec); static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec); struct tasklet_struct { struct tasklet_struct *next; unsigned long state; atomic_t count; void (*func)( unsigned long ); unsigned long data; }; 如何使用 tasklet 使用 tasklet 比较简单,只需要初始化一个 tasklet_struct 结构体,然后调用 tasklet_schedule, 就能利用 tasklet 机制执行初始化的 func 函数。 static inline void tasklet_schedule( struct tasklet_struct *t) { if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) __tasklet_schedule(t); } tasklet_schedule 处理过程也比较简单,就是把 tasklet_struct 结构体挂到 tasklet_vec 链表或者挂接到 tasklet_hi_vec 链表上,并调度软中断 TASKLET_SOFTIRQ 或者 HI_SOFTIRQ 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 = &(t->next); raise_softirq_irqoff(TASKLET_SOFTIRQ); local_irq_restore(flags); } EXPORT_SYMBOL(__tasklet_schedule); void __tasklet_hi_schedule( struct tasklet_struct *t) { unsigned long flags; local_irq_save(flags); t->next = NULL; *__get_cpu_var(tasklet_hi_vec).tail = t; __get_cpu_var(tasklet_hi_vec).tail = &(t->next); raise_softirq_irqoff(HI_SOFTIRQ); local_irq_restore(flags); } EXPORT_SYMBOL(__tasklet_hi_schedule); Tasklet 执行过程 Tasklet_action 在软中断 TASKLET_SOFTIRQ 被调度到后会被执行,它从 tasklet_vec 链表中把 tasklet_struct 结构体都取下来,然后逐个执行。如果 t->count 的值等于 0 ,说明这个 tasklet 在调度之后,被 disable 掉了,所以会将 tasklet 结构体重新放回到 tasklet_vec 链表,并重新调度 TASKLET_SOFTIRQ 软中断,在之后 enable 这个 tasklet 之后重新再执行它。 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 = &__get_cpu_var(tasklet_vec).head; local_irq_enable(); while (list) { struct tasklet_struct *t = list; list = list->next; if (tas

本文系统(linux)相关术语:linux系统 鸟哥的linux私房菜 linux命令大全 linux操作系统

主题: CPU数据结构TI数据其实
分页:12
转载请注明
本文标题:tasklet机制和工作队列
本站链接:http://www.codesec.net/view/484394.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 系统(linux) | 评论(0) | 阅读(36)