使用定时器对象

使用定时器对象

以下图表说明了怎么样使用一个通知定时器去为一个操作设定一个超时事件,然后等待其他驱动例程处理一个IO请求。


如上图表所示,驱动程序必须为定时器对象提供存储空间,并以它作为参数为这个定时器对象调用KeInitializeTimer初始化定时器。驱动程序通常在AddDevice中调用这个函数。在一个特定的线程的上下文中,像是一个驱动创建的线程或是一个正在请求一个同步IO操作的线程,驱动程序可以像上面图表显示的(流程)一样等待它的定时器对象:

1. 

一个线程调用KeSetTimer 并以定时器对象和一个指定的DueTime作为参数,DueTime100纳秒为单位。DueTime如果是一个正数,那么它指定了一个绝对时间,在那个绝对时间到来后定时器对象应当从内核的定时器队列中删除并且设置为信号态。DueTime如果是一个负值,那么它以当前的系统时间为准指定一个相对的时间间隔。

 

注意如果线程(或者运行在系统线程中的驱动例程)在一个定时器上等待而非插入一个CustomTimerDpc例程,那么它调用KeSetTimer时当传递一个NULL指针给DPC对象(shown previously in the figure illustrating using timer and DPC objects for a CustomTimerDpc routine)参数。

2. 

在定时器对象处于内核队列中时,线程以此定时器对象为参数调用KeWaitForSingleObject将会把本线程挂起(置于等待状态)。

3. 

给定的DueTime到期。

4. 

内核把定时器对象移出队列,设置它为信号态,然后改变等待它的线程的状态,从等待(waiting)到准备好(ready)。

5. 

内核在一个处理器可用时尽快调度此线程运行(所谓可用指的是):没有其他更高优先级的线程当前正处于准备好状态,并且没有在更高IRQL上运行的内核例程。

 

运行在IRQL >= DISPATCH_LEVEL的驱动程序例程可以使用一个带相关联DPC对象的定时器对象插入一个驱动提供的CustomTimerDpc例程,通过这种方式可以为一个请求设定超时。仅那些运行在“非任意”线程上下文的驱动例程可以在一个定时器对象上等待一个非0时间,如前图所示。

像其他线程一样,一个驱动创建的线程被一个内核线程对象所代表,(这个内核对象)同样也是一个调度对象。因此,驱动程序的(驱动创建的)线程无需使用一个定时器对象去在一个给定的时间内自愿进入一个等待状态。作为替代,线程可以使用KeDelayExecutionThread并传递给定的调用者提供的时间间隔给这个函数。更多有关此技术的信息,见Polling a Device.

DriverEntryReinitialize Unload 例程同样运行在一个系统线程的上下文中,所以驱动程序可以用一个它初始化的定时器对象作为参数调用KeWaitForSingleObject 或者是KeDelayExecutionThread,当他们初始化或者是卸载时。一个设备驱动程序如果必须在它初始化时需要等待设备更新状态,可以调用KeStallExecutionProcessor提供一个非常短的时间间隔(小于50毫秒最佳)

然而,高层级的驱动程序一般在他们的DriverEntryReinitialize使用其他同步机制而不是定时器对象。高层级的驱动程序应当总是被设计为附加在其他底层级的(一种或者多种特定的设备的)驱动程序上。因此,一个高层级的驱动程序在等待一个定时器对象或者调用KeDelayExecutionThread的时候往往会变慢,因为这样的一个驱动程序必须等待一个足够长的时间去适应最慢速的设备以支持它。同样要注意(用于等待的)一个“安全”但是最小的时间是非常难以确定的。相似的,PnP驱动程序不应当等待其他动作发生,而应当使用PnP管理器的notification机制。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值