高级语言程序设计(C++)

高级语言程序设计(C++)

ID:28370141

大小:189.00 KB

页数:40页

时间:2018-12-09

高级语言程序设计(C++)_第1页
高级语言程序设计(C++)_第2页
高级语言程序设计(C++)_第3页
高级语言程序设计(C++)_第4页
高级语言程序设计(C++)_第5页
资源描述:

《高级语言程序设计(C++)》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、WDM驱动程序设计同步技术第5讲主要内容一个同步问题的例子中断请求级自旋锁内核同步对象其它内核同步原语一个同步问题的例子下面利用静态变量lActiveRequests记录当前未完成的I/O请求数:staticLONGlActiveRequests;NTSTATUSDispatchPnp(PDEVICE_OBJECTfdo,PIRPIrp){++lActiveRequests;...//processPNPrequest--lActiveRequests;}有什么问题?关于语句“++lActiveRequests”在X86处理器上汇编程序生成如下代码://++lActiveReq

2、uests;moveax,lActiveRequestsaddeax,1movlActiveRequests,eax上述代码的第三条指令被执行之前如果被同一CPU上的其它执行线程打断,或者在不同CPU上有完全相同的代码在同时运行都会引起++lActiveRequests的计数错误。解决的办法把load/add/store和load/subtract/store指令序列替换为原子指令://++lActiveRequests;inclActiveRequests//--lActiveRequests;declActiveRequestsINC和DEC指令不能被中断,但是多处理器环境

3、中仍然是不安全的,因为这两个指令都是由几条微代码实现的。最终解决办法//++lActiveRequests;lockinclActiveRequests//--lActiveRequests;lockdeclActiveRequestsLOCK指令前缀可以使当前执行多微码指令的CPU锁定总线,从而保证数据访问的完整性。两个最差的假定驱动程序开发者必须做如下两个最差的假定:操作系统可以在任何时间抢先任何例程并停留任何长的时间,所以我们不能保证自己的任务不被干扰或延迟。即使我们能防止被抢先,但其它CPU上执行的代码也会干扰我们代码的执行,甚至一个程序的代码可以在两个不同线程的上下文

4、中并发执行。同步请求级一个确定的CPU上的活动仅能被拥有更高IRQL的活动抢先。IRQL与线程优先级线程优先级是与IRQL非常不同的概念。线程优先级控制着OS线程调度器的调度动作,决定何时抢先运行线程以及下一次运行什么线程。当IRQL级高于或等于DISPATCH_LEVEL级时线程切换停止,无论当前活动的是什么线程都将保持活动状态直到IRQL降到DISPATCH_LEVEL级之下。在进行线程调度时会切换线程上下文;按照IRQL进行活动抢先时不会切换线程上下文。利用IRQL进行同步方法:将所有对共享数据的访问都应该在同一(提升的,高于PASSIVE_LEVEL级的)IRQL上进行

5、。上述方法只适用于单CPU。可利用KeRaiseIrql和KeLowerIrql函数改变当前IRQL。KIRQLoldirql;ASSERT(KeGetCurrentIrql()<=DISPATCH_LEVEL);KeRaiseIrql(DISPATCH_LEVEL,&oldirql);++lActiveRequests;...KeLowerIrql(oldirql);自旋锁(spinlock)利用自旋锁可以解决多处理器平台上的同步问题。一个自旋锁对应一个内存变量。为了获得一个自旋锁,在某CPU上运行的代码需先执行一个原子操作,该操作测试并设置(test-and-set)某个内

6、存变量,由于它是原子操作,所以在该操作完成之前其它CPU不可能访问这个内存变量。如果测试结果表明锁已经空闲,则程序获得这个自旋锁并继续执行。如果测试结果表明锁仍被占用,程序将在一个小的循环内重复这个“测试并设置(test-and-set)”操作,即开始“自旋”。最后,锁的所有者通过重置该变量释放这个自旋锁,于是,某个等待的test-and-set操作向其调用者报告该自旋锁已释放。使用自旋锁时的注意事项第一,如果一个已经拥有某个自旋锁的CPU想第二次获得这个自旋锁,则该CPU将死锁(deadlock)。第二,CPU在等待自旋锁时不做任何有用的工作,仅仅是等待。所以,为了避免影响性

7、能,你应该在拥有自旋锁时做尽量少的操作,因为此时某个CPU可能正在等待这个自旋锁。第三,仅能在低于或等于DISPATCH_LEVEL级上请求自旋锁,在你拥有自旋锁期间,内核将把你的代码提升到DISPATCH_LEVEL级上运行。如何使用自旋锁首先,在非分页内存中为一个KSPIN_LOCK对象分配存储空间。然后调用KeInitializeSpinLock初始化这个对象。typedefstruct_DEVICE_EXTENSION{...KSPIN_LOCKQLock;}DEVICE_EXTEN

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。