lmycs
驱动牛犊
驱动牛犊
  • 注册日期2001-07-23
  • 最后登录2002-12-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2073回复:15

为何自旋锁未能起作用?

楼主#
更多 发布于:2002-05-24 11:16
我在AddDevice里初始化了一个SPINLOCK然后在DispatchIOCtl例程的某两个(设为A,B)IoCtl的处理代码段中用KeAcquireSpinLock和KeReleaseSpinLock各锁住一段代码,结果发现先到来的A获得锁但未释放时,后到来的B竟也能获得锁进入了关键代码段.我以前从为见过这种现象,想不通为什么?或者是我疏忽了什么?请各位提点建议.在下不胜感激.

最新喜欢:

baoyibao99baoyib...
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
沙发#
发布于:2002-05-24 15:04
锁初始化错误?导致这两个函数失败吧。检查一下输入参数和返回值,看看是什么错误码。
panxi
驱动牛犊
驱动牛犊
  • 注册日期2001-06-09
  • 最后登录2018-05-30
  • 粉丝0
  • 关注0
  • 积分22分
  • 威望101点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-05-24 15:12
自旋锁是针对多CPU而言的,对单CPU并没有任何的作用
monkeyy
驱动中牛
驱动中牛
  • 注册日期2001-12-06
  • 最后登录2010-10-10
  • 粉丝0
  • 关注0
  • 积分315分
  • 威望84点
  • 贡献值0点
  • 好评度32点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-05-24 16:38
自旋锁是用于互斥资源的访问的,好象与CPU个数无关喔??
听说老虎会吃人,所以从没想过去摸老虎的屁股。:( :(
matt
驱动中牛
驱动中牛
  • 注册日期2001-07-24
  • 最后登录2016-02-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-05-24 17:32
自旋锁是针对多CPU而言的,对单CPU并没有任何的作用


对uniprocessor及multi-processor,SpinLock的实现机制不一样,但其结果是一样的,即实现互斥。

不妨把程序段贴出来。如果你的实现与你所说的一致,也不会出现此类问题。
System Internals http://sys.xiloo.com
.X.T.I.M.
驱动大牛
驱动大牛
  • 注册日期2001-09-22
  • 最后登录2021-08-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-05-24 17:59
是不是啊??你用VERIFIER来看看获得了几次SPINLOCK的时候出现这个问题的??单数还是双数??
<IMG src="http://www.microsoft.com/traincert/images/logos/mcp.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcdba.gif" border=0><br> <IMG src="http://www.microsoft.com/traincert/images/logos/mcse.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcsd.gif" border=0>
panxi
驱动牛犊
驱动牛犊
  • 注册日期2001-06-09
  • 最后登录2018-05-30
  • 粉丝0
  • 关注0
  • 积分22分
  • 威望101点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-05-25 16:53
我以前也想用自旋锁做互斥,后来发现根本不灵,锁住后一样可以
进去,后来我就改用别的方式了,

我和linux下写驱动的人讨论过这个问题,他们说linux下的自旋锁
也有同样的现象,ddk文档写自旋锁就是在多CPU之间做互斥的

.X.T.I.M.
驱动大牛
驱动大牛
  • 注册日期2001-09-22
  • 最后登录2021-08-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-05-25 17:15
我以前也想用自旋锁做互斥,后来发现根本不灵,锁住后一样可以
进去,后来我就改用别的方式了,

我和linux下写驱动的人讨论过这个问题,他们说linux下的自旋锁
也有同样的现象,ddk文档写自旋锁就是在多CPU之间做互斥的

 

WHO说的WHO说的??如果真的是不灵的话,就不存在资源保护了!你做过没有啊??不要随便听谣言!MS的东西MS说的还是比较权威的!我估计是他的代码的问题而不是SPINLOCK的问题~
<IMG src="http://www.microsoft.com/traincert/images/logos/mcp.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcdba.gif" border=0><br> <IMG src="http://www.microsoft.com/traincert/images/logos/mcse.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcsd.gif" border=0>
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
8楼#
发布于:2002-05-25 19:47
不会吧?DDK里面好多用自镟锁的,怎么会不灵?
zdhe
驱动太牛
驱动太牛
  • 注册日期2001-12-26
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分72362分
  • 威望362260点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
9楼#
发布于:2002-05-25 21:32
spinlock will not work in dispatch level or higher.

in dispatch level or higher, program need not dealing this, beucase no thread context switch  :D :D :D

we use spinlock only when we need , not because we want to use it.
.X.T.I.M.
驱动大牛
驱动大牛
  • 注册日期2001-09-22
  • 最后登录2021-08-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-05-25 21:45
SPINLOOK永远都是在DIRQL工作的!!不会高也不会低!!从PASSIVE和DISPATCH都可以调用!只要是在内核层内!而且不低于DIRQL都可以调用!!!其实SPINLOCK的原理很简单!就是把某段代码放到DIRQL运行,并为它维护一个句柄!这个句柄同时只能有一个线程可以获得,获得这个句柄就好象门票一样!不过是出来的时候要还给IO管理器罢了!
<IMG src="http://www.microsoft.com/traincert/images/logos/mcp.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcdba.gif" border=0><br> <IMG src="http://www.microsoft.com/traincert/images/logos/mcse.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcsd.gif" border=0>
zdhe
驱动太牛
驱动太牛
  • 注册日期2001-12-26
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分72362分
  • 威望362260点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
11楼#
发布于:2002-05-25 21:58
form walt oney:


自旋锁

--------------------------------------------------------------------------------

IRQL概念仅能解决单CPU上的同步问题,在多处理器平台上,它不能保证你的代码不被运行在其它处理器上的代码所干扰。一个称为自旋锁(spin lock)的原始对象可以解决这个问题。为了获得一个自旋锁,在某CPU上运行的代码需先执行一个原子操作,该操作测试并设置(test-and-set)某个内存变量,由于它是原子操作,所以在该操作完成之前其它CPU不可能访问这个内存变量。如果测试结果表明锁已经空闲,则程序获得这个自旋锁并继续执行。如果测试结果表明锁仍被占用,程序将在一个小的循环内重复这个“测试并设置(test-and-set)”操作,即开始“自旋”。最后,锁的所有者通过重置该变量释放这个自旋锁,于是,某个等待的test-and-set操作向其调用者报告锁已释放。

关于自旋锁有两个明显的事实。第一,如果一个已经拥有某个自旋锁的CPU想第二次获得这个自旋锁,则该CPU将死锁(deadlock)。自旋锁没有与其关联的“使用计数器”或“所有者标识”;锁或者被占用或者空闲。如果你在锁被占用时获取它,你将等待到该锁被释放。如果碰巧你的CPU已经拥有了该锁,那么用于释放锁的代码将得不到运行,因为你使CPU永远处于“测试并设置”某个内存变量的自旋状态。

关于自旋锁的另一个事实是,CPU在等待自旋锁时不做任何有用的工作,仅仅是等待。所以,为了避免影响性能,你应该在拥有自旋锁时做尽量少的操作,因为此时某个CPU可能正在等待这个自旋锁。

关于自旋锁还存在着一个不太明显但很重要的事实:你仅能在低于或等于DISPATCH_LEVEL级上请求自旋锁,在你拥有自旋锁期间,内核将把你的代码提升到DISPATCH_LEVEL级上运行。在内部,内核能在高于DISPATCH_LEVEL的级上获取自旋锁,但你和我都做不到这一点。

matt
驱动中牛
驱动中牛
  • 注册日期2001-07-24
  • 最后登录2016-02-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-05-26 21:02
SPINLOOK永远都是在DIRQL工作的!!不会高也不会低!!从PASSIVE和DISPATCH都可以调用!只要是在内核层内!而且不低于DIRQL都可以调用!!!其实SPINLOCK的原理很简单!就是把某段代码放到DIRQL运行,并为它维护一个句柄!这个句柄同时只能有一个线程可以获得,获得这个句柄就好象门票一样!不过是出来的时候要还给IO管理器罢了!


SPINLOOK有很多种类的,普通spinlock的将提升IRQL至Dispatch Level

参见http://sys.xiloo.com/documents/irql.htm

System Internals http://sys.xiloo.com
panxi
驱动牛犊
驱动牛犊
  • 注册日期2001-06-09
  • 最后登录2018-05-30
  • 粉丝0
  • 关注0
  • 积分22分
  • 威望101点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-05-27 08:53
关于自旋锁,我写了一段代码:
在资源初始化结束后,

KIRQL OldIrql0,OldIrql1;
KeInitializeSpinLock(&dx->SpinLock);
//1
KeAcquireSpinLock(&dx->SpinLock,&OldIrql0);
KeAcquireSpinLock(&dx->SpinLock,&OldIrql1);
KeReleaseSpinLock(&dx->SpinLock,OldIrql1);
KeReleaseSpinLock(&dx->SpinLock,OldIrql0);
//2
DebugPrint(\"ok!\");

这段代码应当会死锁,但实际运行中没有死锁,
为了测试在不同的irql上运行,我在1处
加了升高irql到DISPATCH_LEVEL的代码,
在2处将IRQL降到PASSIVE_LEVEL

还是没有死锁。

有没有人可以解释一些

matt
驱动中牛
驱动中牛
  • 注册日期2001-07-24
  • 最后登录2016-02-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-05-27 10:32
关于自旋锁,我写了一段代码:
在资源初始化结束后,

KIRQL OldIrql0,OldIrql1;
KeInitializeSpinLock(&dx->SpinLock);
//1
KeAcquireSpinLock(&dx->SpinLock,&OldIrql0);
KeAcquireSpinLock(&dx->SpinLock,&OldIrql1);
KeReleaseSpinLock(&dx->SpinLock,OldIrql1);
KeReleaseSpinLock(&dx->SpinLock,OldIrql0);
//2
DebugPrint(\"ok!\");

这段代码应当会死锁,但实际运行中没有死锁,
为了测试在不同的irql上运行,我在1处
加了升高irql到DISPATCH_LEVEL的代码,
在2处将IRQL降到PASSIVE_LEVEL

还是没有死锁。

有没有人可以解释一些

 


对于uniprocessor,这段代码不会死锁,对多处理器系统那是100%死锁。因为实现机理不一样。

SpinLock一般用于多个任务之间的互锁,你这样用实际违背了其原意。
System Internals http://sys.xiloo.com
matt
驱动中牛
驱动中牛
  • 注册日期2001-07-24
  • 最后登录2016-02-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2002-05-27 10:35
关于自旋锁,我写了一段代码:
在资源初始化结束后,

KIRQL OldIrql0,OldIrql1;
KeInitializeSpinLock(&dx->SpinLock);
//1
KeAcquireSpinLock(&dx->SpinLock,&OldIrql0);
KeAcquireSpinLock(&dx->SpinLock,&OldIrql1);
KeReleaseSpinLock(&dx->SpinLock,OldIrql1);
KeReleaseSpinLock(&dx->SpinLock,OldIrql0);
//2
DebugPrint(\"ok!\");

这段代码应当会死锁,但实际运行中没有死锁,
为了测试在不同的irql上运行,我在1处
加了升高irql到DISPATCH_LEVEL的代码,
在2处将IRQL降到PASSIVE_LEVEL

还是没有死锁。

有没有人可以解释一些

 


你不妨在你的dispatch routine中这样试试,Acquire之后不release...

保证会死锁.
System Internals http://sys.xiloo.com
游客

返回顶部