Windows 自旋锁分析(二)

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    dwordptr [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) ;
     }
     elsebreak;
    }
}
对比一下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的惜指令如金。


你可能感兴趣的:(windows,工作,汇编,存储,byte)