阅读:2381回复:6
SMP系统下KeAcquireSpinLock 的疑问。
本论坛的一篇经验文章《Windows NT 驱动程序开发人员提示 -- 应注意避免的事项》中提到:
14. 一定不要在 ISR 或 SynchCritSection 例程中调用 KeAcquireSpinLock 和 KeReleaseSpinLock 或者其它任何使用可执行旋转锁的例程。 但是,如果ISR中确实需要调用KeAcquireSpinLock怎么办?KeAcquireSpinLock 应该本来就是为解决多CPU情况下的问题。 请各位指教! |
|
沙发#
发布于:2008-09-11 00:42
KeAcquireSpinLock 会提升IRQL?
晕 |
|
板凳#
发布于:2008-09-11 11:13
call KeAcquireSpinLock when IRQL<=DISPATCH....
|
|
地板#
发布于:2008-09-12 09:49
因为KeAcquireSpinLock 会把irql提升到dpc,
你可以自己实现一个同步操作,类似spinlock,主要使用lock bts和pause指令,如果你的isr比较简单,并且阻塞的时间比较短。 |
|
地下室#
发布于:2008-09-12 11:14
多谢
windows下有lock bts和pause这些指令么?你的意思是说自己做个提升到DIRQL的spinlock吧? |
|
5楼#
发布于:2008-09-17 21:20
为什么需要在ISR里面调用这个函数?
没必要在ISR里面调用这个函数啊 一个驱动程序运行的IRQL大概有3种 1.普通的level..比如passive.这是大多少代码运行的level 2.dispatch level.这个基本上都是同步要求的level 3.isr的level.. 从1到3.一个比一个高 在单cpu的情况下 如果一个isr正在运行..那么系统会保证任何低于isr的level的代码都不会被运行 也就说你的isr在运行的时候是不用担心被别的低level的代码抢占的 而同时的...isr一样有一个spinlock.他跟普通用的executive spinlock不一样 他的irql不是dispatch level而是你的isr的hardware level 在多cpu的情况下 如果你的isr要访问的数据也会被别的代码访问 那么你需要别的代码去同步isr.而不是isr去跟别的代码同步... 明白了吗? 可以这样认为 isr是无视同步的..而别的代码去跟isr同步 别的代码需要获取isr的那个spinlock来做到同步 使用这个函数KeSynchronizeExecution 查一查msdn看看这个函数 通常的..spinlock的用法都是这样 KeAcquireSpinlock(..); [...access some data...] KeReleaseSpinlock(...); 而ISR的情况是这样的 内核调用..KeAcquireSpinlock(&InterruptObject->Spinlock,...); 内核接着调用你的ISR 内核调用..KeReleaseSpinlock(&InterruptObject->Spinlock,...); 也就是说你的ISR在运行的时候你已经获取了你的interrupt object里面的spinlock 对比一下上面的通常情况的部分 你就知道如果别的代码要ISR同步 他只是需要获取和释放interrupt object里面的spin lock就行来 这也就是KeSynchronizeExecution的功能 他的代码大概是这样的 BOOLEAN KeSynchronizeExecution(IN PKINTERRUPT Interrupt,IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,IN PVOID SynchronizeContext) { KeAcquireSpinlock(&Interrupt->Spinlock,...); SynchronizeRoutine(SynchronizeContext); KeReleaseSpinlock(&Interrupt->Spinlock,...); } 也就是说你的isr和上面的SynchronizeRoutine都不需要去管spinlock 内核已经帮你同步好了 |
|
6楼#
发布于:2009-01-08 17:18
时至今日,方才明白tiamo老大这番话的真实含义,太感谢了!!!
祝2009年身体健康。 |
|