- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Windows/Linux/Solaris?软中断处理机制
(2010-02-09 17:52:04)
转载
标签:
软中断
apc
硬件中断
回调函数
it 分类: 在非中断线程化的 OS 中,如果把响应中断的所有工作都在 ISR 中完成,系统是无法忍受的,我们要做的是在 ISR 中尽量的减少代码,只做一些必要性的工作,如 in / out 操作,把一些其他不必要在 ISR 中工作放到其他地方,比如数据的处理,这也就是软中断目的所在。其实即使在中断线程化的 OS 当中(如:SOLARIS)也一样有软中断,但这里的软中断含义和那种推迟调度不是一个概念了。以下仅针对此帖题目举例说明硬件中断如何触发软中断,关于如何注册软中断和注册步骤就不说了。这里所说的软中断是与题目相关的。在 NT KERNEL 中把软件运行环境又分为三个软件中断 IRQL 等级,DISPATCH_LEVEL(DPC_LEVEL),APC_LEVEL,PASSVIE_LEVEL。系统提供的 DPC 是为了处理硬件中断后续工作提供的一种机制,DPC 与 Linux Kernel 提供的基于 tasklet 实现的 Bottom Half 作用上有些相似,但又不一样。在使用 DPC 处理硬件中断后续的工作前,需显示调用相关的 kernel api 注册 DPC。关于硬件中断如何触发 DPC 调用,可以看HalEndSystemInterrupt() 这个函数,在这个函数中,首先确定没有其他嵌套硬件中断后(没有高于 DPC_LEVEL 的 IRQL),把 IRQL 降低,并判断是否有 DPC 调用(之前使用 IoRequestDpc() 向系统注册的 DPC 回调函数,当把 DPC 回调函数插入DPC LIST 后,系统调用 HalRequestSoftwareInterrupt() 设置当前 IRQL 为DPC_LEVEL,如果当前有硬件级的 IRQL 高于 DPC_LEVEL 则 pending DPC),如果有则设置 IRQL 为 DPC_LEVEL 并调用 KiDispatchInterrupt() 处理之前注册的 DPC 回调函数。KiDispatchInterrupt() 函数本身是在 IRQL == DPC_LEVEL 上运行的,它同样是处理线程调度的主函数。也就是说 DPC 调用点不光是在所有硬件ISR 处理完成后调用 DPC。还有是处理任务调度时也会判断是否需要执行 DPC。这里注意,DPC 与 DPC_LEVEL 不是一回事,DPC 回调函数运行级别在 DPC_LEVEL,但并不是说所有 DPC_LEVEL 级别都是要运行 DPC 回调函数的。在非 SMP 环境下spinlock 的实现就是简单的提升当前 IRQL 为 DPC_LEVEL,因为在这个级别的IRQL 下所有其他软件级别运行的代码都将被阻塞,所以说线程调度主函数运行在这个级别是不会被任何线程抢占的,另 DPC_LEVEL 虽然不是中断上下文,但在这个级别下,任何引起睡眠的机制都将导致系统崩溃。扯的有点远了。再简单说下 APC(Asynchronous Procedure Call),故名思意,既然是“异步过程调用”那么当前执行环境很可能是任意线程上下文。其实到了 APC 这里就跟硬件中断扯不上边了,虽然是这样系统还是把 APC 实现也定位为一种软中断,APC 运行在 APC_LEVEL 级别(同样系统调用 HalRequestSoftwareInterrupt() 函数设置当前IRQL 为APC_LEVEL)。关于如何触发 APC 可以去看一些读/写函数,当一个读/写函数设置了异步标志时,有几种情况(因为是异步的),首先说一下触发条件,条件是:“系统处理的当前线程是调用者线程且 IRQL 小于 APC_LEVEL 时从当前线程 APC 队列里取出 APC 回调函数并把 IRQL 提升到 APC_LEVEL 进行调用”。继续看这几种情况,如果系统当前处理线程不是调用者者线程,则清除 APC_LEVEL 标志,并将此 APC(回调函数)插入调用者线程的 APC 列然后返回。如果系统当前处理线程正是调用者线程,那么判断当前 IRQL 是否高于 APC_LEVEL,如果高于则插入调用者线程 APC队列,此次 APC 中断被记录并返回。如果系统当前处理线程是调用者线程且 IRQL小于 APC_LEVEL 则满足调用条件,APC 回调函数立刻被调用。处理 APC 的调用点是在 syscall 返回时检查。在 Linux Kernel 里引入 softirq 机制后,使用 tasklet 来实现 Bottom Half。tasklet 也是 softirq 的一种应用,在使用
文档评论(0)