dshadow79
驱动牛犊
驱动牛犊
  • 注册日期2002-09-29
  • 最后登录2006-04-10
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
阅读:2286回复:5

同步的一点心得

楼主#
更多 发布于:2003-11-26 18:36
最近因为写的东西涉及到了smp相关的东西,随之而来的同步问题困扰了我很长时间。
这几天被郁闷了这么久,写点东西出来给大家共享一下,呵呵,别说我土

先说一下在单cpu下的同步。如果你的驱动仅仅运行在单cpu下,一个irql就可以搞定
所有的同步问题,由低到高:PASSIVE,APC,DISPATCH,只有高于当前的irql才能中断
当前线程。但是如果在smp机器下,其它的cpu就不会受irql的限制,同步问题得自己
搞定了,没有同步量就不会有稳定的驱动。

同步量,开始的时候看ddk,随便选了几个东西就来用。而且DDK里面也提供了很多,
内核的event,mutex,fastmutex,semaphore。如果你在DISPATCH LEVEL下面使用这些
同步量的话,会有随机死机的情况发生,因为DISPATCH LEVEL下面不允许等待--
而这些操作只有在无法立刻满足获取条件的时候才会进入等待状态,也就是随机死
的原因。而且查错也比较麻烦

只有spinlock才可以在DISPATCH LEVEL下面正常使用。因为spinlock的实现机制
很简单,就是测试并置位一个整数值(BTS),满足则返回,不满足则在一个小循环
里等待,所以不会触犯上面的那个条件。
不过正是因为spinlock太简单了,所以如果同一个cpu两次试图获取一个spinlock而
又没有释放的话,那这个cpu就真的锁住了。

不过这种情况大家可能很少碰到,前面的帖子也有人问过这个问题:我重复多次获
取一个spinlock,怎么还是跑得好好的?我可以确定的是,这一定是一台单cpu机器。
因为win系统(2k,xp)下,我跟踪得到的结果是,spinlock的acquire/release都是
空操作--也就是说spinlock在单cpu下面是摆设。只有在smp机器里,spinlock才
真的会发挥作用:acquire是在一个小循环内反复测试一个整数值,release直接把
这个整数值设为0。这种平台下cpu才会出现真的锁住的情况,设计挺好的,不过不
太利于查错,ms考虑的就是多,呵呵


再说一下我遇到的这个问题,2k,smp平台。在MiniportSend/ProtocolReceivePacket
里面设置的同步,等待一个spinlock来访问共享资源。因为ddk里面说这两个回调是
运行在DISPATCH LEVEL下,按理说不会被自己的cpu打断。可是我在实际用的时候
会有偶尔的死锁现象。郁闷了3,4天,偶尔的一次突然发现进入MiniportSend里的
irql是0(PASSIVE LEVEL),反复试了几次,有的时候是0,有的时候是2(DISPATCH LEVEL)
也就是在获取了spinlock后,当前cpu还是会被中断而再次进入MiniportSend,当然会
死锁了……看来ddk也不是完全正确,这里写出来,省得别人再走弯路

最新喜欢:

txysptxysp
antspower
驱动中牛
驱动中牛
  • 注册日期2002-10-17
  • 最后登录2010-08-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-11-26 18:48
我也专门去琢磨做SPINLOCK,也发现在单CPU根本就没有任何作用.
放弃瘟草,现吃李草
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2003-11-27 23:00
NdisAcquireSpinlock把irql提升到2(dispatch level)了呀
dshadow79
驱动牛犊
驱动牛犊
  • 注册日期2002-09-29
  • 最后登录2006-04-10
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-11-28 12:32
我用的是NdisDprAcquireSpinLock。既然ddk里面已经明确说了,是运行在dispatch level的,干嘛不用dpr呢

所以,就出错了,就郁闷了
bingjie
驱动小牛
驱动小牛
  • 注册日期2001-08-15
  • 最后登录2007-11-29
  • 粉丝0
  • 关注0
  • 积分36分
  • 威望5点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-11-28 15:23
即便是单CPU下使用SPIN_LOCK也还是要注意的,一是AcquieSpinlock会提升至DISPATCH_LEVEL,此时被保护的程序段只能使用非分页内存,否则一旦内存被换出去必然蓝屏,还有就是AcquireSpinlock和ReleaseSpinlock的间隔不能太长,时间长了可能就会有问题
bacongong
驱动牛犊
驱动牛犊
  • 注册日期2007-10-10
  • 最后登录2009-01-12
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望31点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-05-24 19:37
引用第2楼arthurtu于2003-11-27 23:00发表的  :
NdisAcquireSpinlock把irql提升到2(dispatch level)了呀


根据我的测试结果,不是这样,NdisDprAcquireSpinLock也不能保证。

有没有手动提升IRQL的函数?
驱网无线,快乐无限
游客

返回顶部