bjab
驱动牛犊
驱动牛犊
  • 注册日期2002-04-06
  • 最后登录2011-06-07
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望35点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
阅读:1773回复:13

有一个问题请教lu0老大

楼主#
更多 发布于:2004-05-25 15:19
这两种用法有何区别?

1。使用KeSynchronizeExecution执行SyncRouting的代码

2。使用KeRaiseIrql提升其IRQL到对应的中断级,等执行完代码后再调用KeLowerIrql降低

最新喜欢:

chilichili
lu0
lu0
论坛版主
论坛版主
  • 注册日期2001-06-10
  • 最后登录2016-04-05
  • 粉丝2
  • 关注0
  • 积分-6311分
  • 威望21111点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-05-25 18:32
KeSynchronizeExecution会获取SPINLOCK.
KeRaiseIrql没有同步动作. 不是用于保护数据的.
Regards, Lu Lin Webmaster of Inside Programming http://www.lu0s1.com
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2004-05-25 21:52
跟在lu0后面续个貂 :D
lu0难得出现一次

在单CPU,提升到dispatch level,和用spin lock一样的
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地板#
发布于:2004-05-25 23:28
不错,在单CPU上SPINLOCK就是把IRQL提升DISPATCH_LEVEL
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
bjab
驱动牛犊
驱动牛犊
  • 注册日期2002-04-06
  • 最后登录2011-06-07
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望35点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-05-26 11:12
既然KeSynchronizeExcution上获得SPINLOCK

而在单CPU上SPINLOCK就是把IRQL提升DISPATCH_LEVEL

那么使用KeRaiseIrql提升到相应的硬件中断级别岂不是比把IRQL提升到DISPATCH_LEVEL更高

那么似乎也能同步

不太理解,望赐教
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-05-26 11:36
既然KeSynchronizeExcution上获得SPINLOCK

而在单CPU上SPINLOCK就是把IRQL提升DISPATCH_LEVEL

那么使用KeRaiseIrql提升到相应的硬件中断级别岂不是比把IRQL提升到DISPATCH_LEVEL更高

那么似乎也能同步

不太理解,望赐教


如果是多个CPU呢?如果这时候调用KeRaiseIrql(),只是某个CPU提升到高级别IRQL,其它的CPU仍然可能存取数据,会产生同步问题。

而获取Spinlock就不一样了,可以防止这种情况发生。

猜的;)

具体我也不太清楚。
bjab
驱动牛犊
驱动牛犊
  • 注册日期2002-04-06
  • 最后登录2011-06-07
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望35点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-05-27 15:25
那么现在假如就只有一个CPU呢?

情况如何?
hangzhoustayer
驱动小牛
驱动小牛
  • 注册日期2002-05-08
  • 最后登录2006-06-19
  • 粉丝1
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-09-03 14:16
spinlock跟提升IRQL的本质还是不一样的吧,在单机上提升IRQL不能保证不被同样优先级的其它调用或更高优先级的代码来访问吧?
tiamo
VIP专家组
VIP专家组
  • 注册日期2002-02-26
  • 最后登录2018-01-09
  • 粉丝17
  • 关注4
  • 积分50分
  • 威望142点
  • 贡献值1点
  • 好评度40点
  • 原创分2分
  • 专家分15分
  • 原创先锋奖
  • 社区居民
8楼#
发布于:2004-09-03 23:40
楼上的说法是不对的....

单cpu上面spinlock只是把irql升到dispatch level...在我的机器上面他只是更新了os的irql并没有编程8259....不知道在有local apic的cpu上面...会是个什么样子...

同时....在比dispatch level更高级别的代码...是不能调用KeAcquireSpinLock的...请仔细看ddk的文档.....

在单cpu上面...如果irql >= dispatch level..那么context swap是禁止的...低irql的代码是不能获得cpu的执行权利的....

如果你代码里面有同级别的代码先后两次或者多次去acquire lock..那么这个代码是有bug的....这个不是lock本身的问题...而是你自己代码使用lock上面的问题......在checked build的os上会bugcheck的....

也就是说如果你真正的按照spin lock的使用法则来使用他的话..
单cpu上....他的作用基本跟raise irql一样...唯一不同的就是...raise irql会真正的编程你的8259(不清楚local apic的cpu会怎样....).....而acquire spin lock不会.......

至于要怎样去保证共享数据....

首先..要明确你的代码一共会执行在哪些irql上面...
passive,apc,dispatch,device...

如果你的数据只是被除device level的以外的代码访问..
使用spin lock
如果他还要被device level的访问到
使用KeSynchronizeExecution.....他会把irql raise到相应的isr使用的device level...单处理器上已经被证明是安全的了...因为不可能有低irql的代码被执行到,也不可能有想要访问这个数据的高irql代码被执行(如果有,那是你程序设计方面的bug...与windows本身无关)....

在多处理器上面....
首先要明白什么是一个spin lock
其实他只是一个dword..

最简单的做法就是
acquire spin lock先检查他的值是不是1
如果是就继续检查
直到变成0
然后把他设置成1

check_loop:
lock bts dword ptr [LockAddress], 0 ;test 0 and set 1
jc check_loop


release spin lock把他设置成0
mov     byte ptr [LockAddress], 0

这个就是spin lock的简单实现....学过操作系统的就知道他的基本思想就是test and lock....使用的是忙等待...

这个spin lock其实是可以运行在任意的irql上面的...
只是windows限制程序员在高irql上面使用spin lock...
而windows自己却高频率的在device irql上面使用spin lock...
这个lock就是你在IoConnectInterrupt的时候使用的spin lock.

这个lock保证任意时刻只有一个isr在运行,即使在多cpu上也一样..
如果你的isr在运行的时候又来了一个中断..即使这个中断被排程到另外的一个cpu上面...那个cpu也只有忙等待...不能作任何的事情..
这个lock也是KeSynchronizeExecution实现的关键.....
使用这个lock能保证你的routine跟isr是同步的...

同步的方法如上......

spin lock...已经其他的所有的同步的方法只是一种手段...一种规则...想要同步访问...就必须遵守这种规则...不遵守规则的话...是没有绝对办法保证同步的...这点很关键...脱离了这个共同规则的前提去说同步是没有任何意义的....

比如...程序规定...访问一个数据必须要进入临界区...如果全部访问这个数据的代码都使用了这个临界区...我们可以说这个数据是被同步的....但是如果某个地方没有使用临界区就去访问了这个数据...那么当然...这个就是bug...但是...你能说这个bug是临界区这个机制造成的么....

明白么...spin lock等等..只是一种期望...并不是强制的...

irql在单cpu上能足够有效的完成同步....只要你适当的raise跟lower.....

以上......
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
9楼#
发布于:2004-09-04 10:03
楼上的说法是不对的....

单cpu上面spinlock只是把irql升到dispatch level...在我的机器上面他只是更新了os的irql并没有编程8259....不知道在有local apic的cpu上面...会是个什么样子...

同时....在比dispatch level更高级别的代码...是不能调用KeAcquireSpinLock的...请仔细看ddk的文档.....

在单cpu上面...如果irql >= dispatch level..那么context swap是禁止的...低irql的代码是不能获得cpu的执行权利的....

如果你代码里面有同级别的代码先后两次或者多次去acquire lock..那么这个代码是有bug的....这个不是lock本身的问题...而是你自己代码使用lock上面的问题......在checked build的os上会bugcheck的....

也就是说如果你真正的按照spin lock的使用法则来使用他的话..
单cpu上....他的作用基本跟raise irql一样...唯一不同的就是...raise irql会真正的编程你的8259(不清楚local apic的cpu会怎样....).....而acquire spin lock不会.......

至于要怎样去保证共享数据....

首先..要明确你的代码一共会执行在哪些irql上面...
passive,apc,dispatch,device...

如果你的数据只是被除device level的以外的代码访问..
使用spin lock
如果他还要被device level的访问到
使用KeSynchronizeExecution.....他会把irql raise到相应的isr使用的device level...单处理器上已经被证明是安全的了...因为不可能有低irql的代码被执行到,也不可能有想要访问这个数据的高irql代码被执行(如果有,那是你程序设计方面的bug...与windows本身无关)....

在多处理器上面....
首先要明白什么是一个spin lock
其实他只是一个dword..

最简单的做法就是
acquire spin lock先检查他的值是不是1
如果是就继续检查
直到变成0
然后把他设置成1

check_loop:
lock bts dword ptr [LockAddress], 0 ;test 0 and set 1
jc check_loop


release spin lock把他设置成0
mov     byte ptr [LockAddress], 0

这个就是spin lock的简单实现....学过操作系统的就知道他的基本思想就是test and lock....使用的是忙等待...

这个spin lock其实是可以运行在任意的irql上面的...
只是windows限制程序员在高irql上面使用spin lock...
而windows自己却高频率的在device irql上面使用spin lock...
这个lock就是你在IoConnectInterrupt的时候使用的spin lock.

这个lock保证任意时刻只有一个isr在运行,即使在多cpu上也一样..
如果你的isr在运行的时候又来了一个中断..即使这个中断被排程到另外的一个cpu上面...那个cpu也只有忙等待...不能作任何的事情..
这个lock也是KeSynchronizeExecution实现的关键.....
使用这个lock能保证你的routine跟isr是同步的...

同步的方法如上......

spin lock...已经其他的所有的同步的方法只是一种手段...一种规则...想要同步访问...就必须遵守这种规则...不遵守规则的话...是没有绝对办法保证同步的...这点很关键...脱离了这个共同规则的前提去说同步是没有任何意义的....

比如...程序规定...访问一个数据必须要进入临界区...如果全部访问这个数据的代码都使用了这个临界区...我们可以说这个数据是被同步的....但是如果某个地方没有使用临界区就去访问了这个数据...那么当然...这个就是bug...但是...你能说这个bug是临界区这个机制造成的么....

明白么...spin lock等等..只是一种期望...并不是强制的...

irql在单cpu上能足够有效的完成同步....只要你适当的raise跟lower.....

以上......

听君一席话,胜读十年书.........
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
hangzhoustayer
驱动小牛
驱动小牛
  • 注册日期2002-05-08
  • 最后登录2006-06-19
  • 粉丝1
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-09-06 14:16
---------------------------------------------
这个spin lock其实是可以运行在任意的irql上面的...
只是windows限制程序员在高irql上面使用spin lock...
而windows自己却高频率的在device irql上面使用spin lock...
这个lock就是你在IoConnectInterrupt的时候使用的spin lock.
---------------------------------------------
谢谢tiamo大侠,我也正是基于os的理论提出我的疑问的.不过我还是有点疑问.spinlock在效果上跟raise irql一致,这个只是建立在windows os实现上高中断Dispacth_level以上级别对用户应用程序是不可剥夺的基础上,诚如你所说windows自己却在高中断级上使用spinlock,那么它自己所调用的这个spinlock应该写中断寄存器的吧?
也就是说它完全可以剥夺用了spinlock的用户程序的执行吧?如果在用户的spinlock中访问了系统临界资源,而如果这个临界资源window系统本身也要访问的话,会不会出现问题呢? linux里面的spinlock实现似乎维持了spinlock的原始意义
Leopard
驱动老牛
驱动老牛
  • 注册日期2001-07-13
  • 最后登录2021-12-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望53点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
  • 社区居民
  • 忠实会员
11楼#
发布于:2004-09-06 18:34
linux里面的spinlock实现似乎维持了spinlock的原始意义
hangzhoustayer
驱动小牛
驱动小牛
  • 注册日期2002-05-08
  • 最后登录2006-06-19
  • 粉丝1
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-09-06 21:02
是啊,照tiamo,lu0,arthurtu他们的说法,windows里面这个spinlock根本就应该叫spinlock
tiamo
VIP专家组
VIP专家组
  • 注册日期2002-02-26
  • 最后登录2018-01-09
  • 粉丝17
  • 关注4
  • 积分50分
  • 威望142点
  • 贡献值1点
  • 好评度40点
  • 原创分2分
  • 专家分15分
  • 原创先锋奖
  • 社区居民
13楼#
发布于:2004-09-07 05:01
有些看不明白你这段话的意思....

嗯.....

那个spinlock的使用只是在中断处理过程中
和KeSynchxxxx的时候才使用.....

这个两个地方都有KeRaiseIrql的调用
这两个调用是个spinlock本身不相关的
并不是spinlock去raise的irql...
实际上...在单cpu上面...这个地方得ACQUIRE_SPIN_LOCK是个什么都不作的空的语句....你用softice在单cpu上跟踪..甚至根本就看不到任何的语句...

其次...我问一句...你能直接去访问那些操作系统的资源么..
比如说cf8,cfc这两个端口...windows是明令禁止你去读写的..
虽然说windows并没有不让你去读去写这个两个端口...但是文档上说得很清楚...这个是规则..是要求..

你应该作得是调用windows提供给你得api....让他们去读去写..(不是所谓WRITE_PORT_XXX的还是)而是HalGetBusDataxxx或者是得到BUS_STANDARD_INTERFACE(似乎是这样拼的吧...呵呵)的接口然后调用其中的函数...

windows提供给你的api会同步好windows使用的共享资源的访问..
但是这个同步在某种意义上说是很困难的...基本不可能在任何一个时刻都能达到这种目的...

所以windows严格的限制了api的调用时间,调用地点,调用环境...只要你按照要求,按照规则来...windows会同步好这些共享资源的访问...否则...不管是谁...都无能为力...

对于那些你自己使用的共享资源...请自己同步好访问...比如是你自己的pci设备的寄存器...比如是你自己的数据结构..请自己作同步的工作...windows会保证不会去访问到这些数据.....

至于这个名字...spinlock...怎么去翻译呢..自旋锁...又怎么去理解呢....
旋...表示自己得不到锁得时候就反复的去获取...
这个就应该是他的含义....

那你们所谓的原始意义是什么呢...spinlock..难道是在任何情况下都能使用就是所谓的原始意义?
linux没有研究过...但是我想....难道linux的spinlock没有任何的使用限制么....不相信....
游客

返回顶部