无唤醒功能的计时器

从Windows 8.1开始,驱动程序可以使用无唤醒计时器来避免不必要地将处理器从低功耗状态唤醒。 通过将处理器保持在低功耗状态,无唤醒计时器可降低功耗,并延长平板电脑或其他移动计算机在电池充电时可以运行的时间。

仅当处理器处于活动运行状态时,计时器才能过期。 如果计时器在处理器处于低功耗状态时达到其过期时间,并且计时器需要立即过期,则计时器必须唤醒处理器。 但是,当无唤醒计时器达到其过期时间并且处理器处于低功耗状态时,此计时器将等待过期,直到处理器由于计时器以外的某种原因唤醒。 作为一个选项,驱动程序可以为无唤醒计时器指定最大延迟容错,以便如果处理器由于某种其他原因未唤醒 (,) 计时器过期后的最大延迟容错范围内,计时器将唤醒处理器。

驱动程序可以使用无唤醒计时器来启动非关键操作,这些操作仅在处理器处于活动状态时才需要执行。 例如,驱动程序可能会使用无唤醒计时器定期将累积的状态信息从内存缓冲区刷新到文件。 此状态信息描述仅在处理器处于活动状态时驱动程序执行的处理工作。 当处理器处于低功耗状态时,不会生成任何状态信息,并且无需唤醒处理器。

若要创建无唤醒计时器,WDM 驱动程序会调用 ExAllocateTimer 例程。 在此调用中,驱动程序在 Attributes 参数中设置EX_TIMER_NO_WAKE标志位。

若要将无唤醒计时器设置为在某个到期时间过期,驱动程序会调用 ExSetTimer 例程。 在此调用中,驱动程序可以指定非唤醒计时器在达到其到期时间后应等待多长时间,然后计时器唤醒处理器。 驱动程序将此可容忍延迟时间写入EXT_SET_PARAMETERS结构中的 NoWakeTolerance 成员,驱动程序将该成员作为输入参数传递给 ExSetTimer 例程。 如果驱动程序将 NoWakeTolerance 成员设置为特殊值EX_TIMER_UNLIMITED_TOLERANCE,则计时器永远不会唤醒处理器,因此在处理器因其他原因唤醒之前无法过期。

Kernel-Mode驱动程序框架 (KMDF) 驱动程序或User-Mode驱动程序框架 (UMDF) 驱动程序可以调用 WdfTimerCreate 方法来创建无唤醒计时器。 在此调用中,驱动程序将指向 WDF_TIMER_CONFIG 结构的指针作为参数传递。 若要创建从不唤醒处理器的无唤醒计时器,驱动程序会将此结构的 TolerableDelay 成员设置为 TolerableDelayUnlimited 常量。 从 Windows 8.1 和 KMDF 版本 1.13 或 UMDF 2.0 开始支持此常量。

与可合并计时器的比较

KeSetCoalescableTimer 例程是在 Windows 7 中引入的。 此例程使驱动程序能够指定在计时器过期时间允许的容错量。 通常,操作系统可以使用此信息将两个或多个计时器中断合并为单个中断。 如果多个计时器的过期时间彼此足够接近,导致其容错时段重叠,则重叠区域中的单个计时器中断可以满足所有这些计时器的计时要求。

计时器合并的主要好处是,它延长了处理器在计时器过期之间可以保持低功耗状态的时间。 因此,驱动程序将计时器合并和无唤醒计时器用于类似目的。

但是,可合并计时器的行为与无唤醒计时器不同。 具体而言,仅当处理器处于低功耗状态时,为无唤醒计时器指定的可容忍延迟才适用,而无论处理器是否处于低功耗状态,都适用为可合并计时器过期指定的容差。 对于可合并计时器,驱动程序可以在过期时间内增加容错量,以降低计时器唤醒处理器的可能性,但增加容差会降低计时器在处理器处于活动状态时的准确性。 相比之下,当处理器处于活动状态时,为无唤醒计时器指定的可容忍延迟不会影响计时器的准确性。 对于许多驱动程序来说,无唤醒计时器可能是降低功耗的更好方法。