Widows下自旋锁的实现
来源:互联网 发布:ubuntu add to dash 编辑:程序博客网 时间:2024/05/01 15:20
In this part, we’ll discuss how the OS realize SpinLocks via IRQL
Realization of SpinLocks:
Spin locks are very commonly used in drivers to protect data that will be accessed by multiple driver routines running at varying IRQLs. But what’s it’s realizaton ?
Every book about “Operating System?will tell us that an atomic test-and-set instruction will be adopted. Is windows os uses this way ? The answer is NO. What windows nt adopts is IRQL. That is the spinlock routines will change the IRQL.
There are some kernel routines to acquire/release SpinLocks available for driver developers. These routines are not strange faces, so I’ll not introduce their functionalities here.
VOID
KeAcquireSpinLock(
IN PKSPIN_LOCK SpinLock,
OUT PKIRQL OldIrql
);
VOID
KeReleaseSpinLock(
IN PKSPIN_LOCK SpinLock,
IN KIRQL NewIrql
);
VOID
KeAcquireSpinLockAtDpcLevel(
IN PKSPIN_LOCK SpinLock
);
VOID
KeReleaseSpinLockFromDpcLevel(
IN PKSPIN_LOCK SpinLock
);
DDk says that “Callers of KeAcquireSpinLock must be running at IRQL <= DISPATCH_LEVEL? for dispatch_level routines, .it would be better to use KeAcuireSpinLockAtDpcLevel, and that callers of KeReleaseSpinLock are running at IRQL DISPATCH_LEVEL, but why ?
The following codes tell us the answer:
kd> u Hal!KeAcquireSpinLock
hal!KeAcquireSpinLock:
80066806 8b4c2404 mov ecx,[esp+0x4]
8006680a e849c7ffff call hal!KfAcquireSpinLock (80062f58)
8006680f 8b4c2408 mov ecx,[esp+0x8]
80066813 8801 mov [ecx],al
80066815 c20800 ret 0x8
hal!KfAcquireSpinLock:
80062f58 33c0 xor eax,eax
// Save current IRQL to al
80062f5a a024f0dfff mov al, [ffdff024]
// Change Current IRQL to Dispatch Level
80062f5f c60524f0dfff02 mov byte ptr [ffdff024],0x2
80062f66 c3 ret
Then we get the result: The acquiration of spin lock is just only improve current IRQL to DISPATCH_LEVEL. So the article “A Catalog of NT Synchronization Mechanisms?(refer. 2) says “Always relying on spin locks to protect access to shared data may be overkill? Because after the SpinLock is acquired , the current IRQL will be DISPATCH_LEVEL and then the NT dispatcher (scheduler) preemption will be disabled.
But for the routine which is already running at DISPATCH_LEVEL, they are advised .to use KeAcquireSpinLockAtDpcLevel instead. We can image what KeAcquireSpinLockAtDpcLevel do?
kd> u KeAcquireSpinLockAtDpcLevel
nt!KeAcquireSpinLockAtDpcLevel:
804022e4 c20400 ret 0x4
nt!KeReleaseSpinLockFromDpcLevel:
804022f4 c20400 ret 0x4
These two routines do nothing, and just return. As all DISPATCH_LEVEL all the routines will be executed synchronously, they can not interrupt each other, i.e. they are alreary synchronized.
When current IRQL > DISPATCH_LEVEL, we are warned never to call spin lock routines , or we’ll get BSOD. Here we get the reason: KeAcquireSpinLock will try to lower the current IRQL, which is not permitted by NT.
Realization of SpinLocks:
Spin locks are very commonly used in drivers to protect data that will be accessed by multiple driver routines running at varying IRQLs. But what’s it’s realizaton ?
Every book about “Operating System?will tell us that an atomic test-and-set instruction will be adopted. Is windows os uses this way ? The answer is NO. What windows nt adopts is IRQL. That is the spinlock routines will change the IRQL.
There are some kernel routines to acquire/release SpinLocks available for driver developers. These routines are not strange faces, so I’ll not introduce their functionalities here.
VOID
KeAcquireSpinLock(
IN PKSPIN_LOCK SpinLock,
OUT PKIRQL OldIrql
);
VOID
KeReleaseSpinLock(
IN PKSPIN_LOCK SpinLock,
IN KIRQL NewIrql
);
VOID
KeAcquireSpinLockAtDpcLevel(
IN PKSPIN_LOCK SpinLock
);
VOID
KeReleaseSpinLockFromDpcLevel(
IN PKSPIN_LOCK SpinLock
);
DDk says that “Callers of KeAcquireSpinLock must be running at IRQL <= DISPATCH_LEVEL? for dispatch_level routines, .it would be better to use KeAcuireSpinLockAtDpcLevel, and that callers of KeReleaseSpinLock are running at IRQL DISPATCH_LEVEL, but why ?
The following codes tell us the answer:
kd> u Hal!KeAcquireSpinLock
hal!KeAcquireSpinLock:
80066806 8b4c2404 mov ecx,[esp+0x4]
8006680a e849c7ffff call hal!KfAcquireSpinLock (80062f58)
8006680f 8b4c2408 mov ecx,[esp+0x8]
80066813 8801 mov [ecx],al
80066815 c20800 ret 0x8
hal!KfAcquireSpinLock:
80062f58 33c0 xor eax,eax
// Save current IRQL to al
80062f5a a024f0dfff mov al, [ffdff024]
// Change Current IRQL to Dispatch Level
80062f5f c60524f0dfff02 mov byte ptr [ffdff024],0x2
80062f66 c3 ret
Then we get the result: The acquiration of spin lock is just only improve current IRQL to DISPATCH_LEVEL. So the article “A Catalog of NT Synchronization Mechanisms?(refer. 2) says “Always relying on spin locks to protect access to shared data may be overkill? Because after the SpinLock is acquired , the current IRQL will be DISPATCH_LEVEL and then the NT dispatcher (scheduler) preemption will be disabled.
But for the routine which is already running at DISPATCH_LEVEL, they are advised .to use KeAcquireSpinLockAtDpcLevel instead. We can image what KeAcquireSpinLockAtDpcLevel do?
kd> u KeAcquireSpinLockAtDpcLevel
nt!KeAcquireSpinLockAtDpcLevel:
804022e4 c20400 ret 0x4
nt!KeReleaseSpinLockFromDpcLevel:
804022f4 c20400 ret 0x4
These two routines do nothing, and just return. As all DISPATCH_LEVEL all the routines will be executed synchronously, they can not interrupt each other, i.e. they are alreary synchronized.
When current IRQL > DISPATCH_LEVEL, we are warned never to call spin lock routines , or we’ll get BSOD. Here we get the reason: KeAcquireSpinLock will try to lower the current IRQL, which is not permitted by NT.
- Widows下自旋锁的实现
- Widows 下的 Hook
- 自旋锁的实现
- Linux下用户态自旋锁的实现
- Widows下的命令行过滤
- widows下的一些命令
- 自旋锁与互斥锁的对比、手工实现自旋锁
- widows xp下GT4的安装
- widows下mysql的注册与安装
- Widows下php的Redis配置
- Java 中自旋锁的实现
- nginx spinlock 自旋锁的实现
- 自旋锁SPIN LOCK的编程实现
- 基于CAS自旋实现的乐观锁
- nginx spinlock 自旋锁的实现
- 自旋锁公平性的三种实现
- 自旋功能的实现
- Linux下原子操作(信号量 自旋锁)的实现原理和底层代码分析
- “左耳进右耳出”英语怎么说
- XP home版安装IIS方法
- 同事不仅仅是同事,还是朋友。
- 常见内存问题
- 时间越来越紧了!
- Widows下自旋锁的实现
- SQL Server安全认证知识【2】
- Penetration Testing IPsec VPNs
- java如何访问Oracle的long类型?
- 关于Debug和Release之本质区别的讨论
- 北大2218题
- 汉化英文游戏有什么意义?
- 一个无聊男人的疯狂《数据结构与算法分析-C++描述》学习笔记 用C++/lua/python/bash的四重实现(5)欧几里得算法欧几里得算法求最大公约数
- 说“诡”道“诈”——解读“兵者,诡道也”+——文献综述