Windows 自旋锁分析(二)

来源:互联网 发布:淘宝卖家免费装修模板 编辑:程序博客网 时间:2024/05/20 14:41

3 KeAcquireSpinLockAtDpcLevel的实现机制
MSDN上说明调用KeAcquireSpinLockAtDpcLevel的程序必须运行在DISPATCH_LEVEL上。


在多核处理器(Windows2003)下
先来查看一下KeAcquireSpinLockAtDpcLevel的汇编代码
nt!KeAcquireSpinLockAtDpcLevel:
mov ecx,dword ptr [esp+4]
nt!KeAcquireSpinLockAtDpcLevel+0x4
lock bts dword ptr [ecx],0
jb nt!KeAcquireSpinLockAtDpcLevel+0xe
ret 4
nt!KeAcquireSpinLockAtDpcLevel+0xe:
test dword ptr [ecx],1
je nt!KeAcquireSpinLockAtDpcLevel+0x4
pause
jmp nt!KeAcquireSpinLockAtDpcLevel+0xe
将KeAcquireSpinLockAtDpcLevel翻译成伪代码:
KeAcquireSpinLockAtDpcLevel (SpinLock){
while(TRUE) {
//独占处理器和相关存储空间执行下面代码
lastbit=SpinLock.lastbit;
SpinLock.lastbit=1;
//释放独占
if(lastbit ==1){
  while(SpinLock.lastbit ==1) ;
}
else break;
}
}
对比一下KfAcquireSpinLock,KeAcquireSpinLockAtDpcLevel除了不提升IRQL到DISPATCH_LEVEL,其他都是一样的,KeAcquireSpinLockAtDpcLevel的运行环境已经在DISPATCH_LEVEL上了,确实也不要提升。


KefReleaseSpinLockFromDpcLevel的实现
nt!KefReleaseSpinLockFromDpcLevel:
lock and byte ptr [ecx],0

ret
KefReleaseSpinLockFromDpcLevel就是简单实用lock指令把Spinlock的值置成0释放。

在单核处理器(WindowsXP)下
在单核处理器下KfAcquireSpinLock所作的工作就是简单提升一下IRQL到DISPATCH_LEVEL,那么KeAcquireSpinLockAtDpcLevel已经在DISPATCH_LEVEL,还需要做什么工作呢?是不是什么工作都不需要做了?
实际上观察KeAcquireSpinLockAtDpcLevel在单核处理器下的实现,发现确实什么也没做,直接返回了。
KefReleaseSpinLockFromDpcLevel也是一样,直接返回了。


分析:
关于KeAcquireSpinLockAtDpcLevel在MSDN上有这样一段文字:
当IRQL= DISPATCH_LEVEL时,驱动调用KeAcquireSpinLockAtDpcLevel比调用KeAcquireSpinLock 有更好的性能。当IRQL<DISPATCH_LEVEL时,驱动必须调用KeAcquireSpinLock。
其实观察具体实现,KeAcquireSpinLockAtDpcLevel “更好的性能”体现在多核状态下少运行了两条MOV指令,单核状态下少运行了三条MOV指令和一条SHR指令,不得不感叹下Windows的惜指令如金。

0 0
原创粉丝点击