阅读:1773回复:13
有一个问题请教lu0老大
这两种用法有何区别?
1。使用KeSynchronizeExecution执行SyncRouting的代码 2。使用KeRaiseIrql提升其IRQL到对应的中断级,等执行完代码后再调用KeLowerIrql降低 |
|
最新喜欢:chili |
沙发#
发布于:2004-05-25 18:32
KeSynchronizeExecution会获取SPINLOCK.
KeRaiseIrql没有同步动作. 不是用于保护数据的. |
|
|
板凳#
发布于:2004-05-25 21:52
跟在lu0后面续个貂 :D
lu0难得出现一次 在单CPU,提升到dispatch level,和用spin lock一样的 |
|
地板#
发布于:2004-05-25 23:28
不错,在单CPU上SPINLOCK就是把IRQL提升DISPATCH_LEVEL
|
|
|
地下室#
发布于:2004-05-26 11:12
既然KeSynchronizeExcution上获得SPINLOCK
而在单CPU上SPINLOCK就是把IRQL提升DISPATCH_LEVEL 那么使用KeRaiseIrql提升到相应的硬件中断级别岂不是比把IRQL提升到DISPATCH_LEVEL更高 那么似乎也能同步 不太理解,望赐教 |
|
5楼#
发布于:2004-05-26 11:36
既然KeSynchronizeExcution上获得SPINLOCK 如果是多个CPU呢?如果这时候调用KeRaiseIrql(),只是某个CPU提升到高级别IRQL,其它的CPU仍然可能存取数据,会产生同步问题。 而获取Spinlock就不一样了,可以防止这种情况发生。 猜的;) 具体我也不太清楚。 |
|
6楼#
发布于:2004-05-27 15:25
那么现在假如就只有一个CPU呢?
情况如何? |
|
7楼#
发布于:2004-09-03 14:16
spinlock跟提升IRQL的本质还是不一样的吧,在单机上提升IRQL不能保证不被同样优先级的其它调用或更高优先级的代码来访问吧?
|
|
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..... 以上...... |
|
9楼#
发布于:2004-09-04 10:03
楼上的说法是不对的.... 听君一席话,胜读十年书......... |
|
|
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的原始意义 |
|
11楼#
发布于:2004-09-06 18:34
linux里面的spinlock实现似乎维持了spinlock的原始意义
|
|
12楼#
发布于:2004-09-06 21:02
是啊,照tiamo,lu0,arthurtu他们的说法,windows里面这个spinlock根本就应该叫spinlock
|
|
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没有任何的使用限制么....不相信.... |
|