Windows内核与原理读书笔记之DPC和时钟中断和定时器管理

时间:2024-04-09 20:22:25

1.DPC(延迟过程调用)

DPC有普通的(normal) 和线程的(threaded)。普通的DPC可以在任何一个线程环境中运行,线程的DPC只能在一个专门的DPC线程中运行。

WRK 中DPC对象定义:

typedef struct _KDPC {

    UCHAR Type;

    UCHAR Importance;

    UCHAR Number;

    UCHAR Expedite;

    LIST_ENTRY DpcListEntry;

    PKDEFERRED_ROUTINE DeferredRoutine;

    PVOID DeferredContext;

    PVOID SystemArgument1;

    PVOID SystemArgument2;

    PVOID DpcData;

} KDPC, *PKDPC, *PRKDPC;

Type 说明DPC的对象类型,可能未DpcObject 或ThreadedDpcObject。

Importance 说明了一个DPC对象的重要程度,可以为低(LowImportance)、中(MediumImportance)或高(HighImportance)。当重要程度为高时,DPC对象被插入到DPC链表的头部,否则插入到尾部。

Number 指明DPC对象的目标处理器。

Expedite 保留成员。

DpcListEntry 是DPC对象加入到DPC链表中的节点对象。

DeferredRoutine 是真正被延迟执行的函数指针。

DeferredContext 可以指向任意数据结构,在DPC对象初始化时指定。

SystemArgument1、SystemArgument2 是延迟函数被执行时的两个参数。

DPCData 记录了它被插入到哪个DPC链表中。

根据在插入时是否触发软件中断,DPC对象在以下三种情况下被交付:

  1. 当处理器的IRQL从DISPATCH_LEVEL或更高级别降低到APC_LEVEL 或PASSIVE_LEVEL时,内核开始处理该处理器的DPC链表中的DPC对象,依次调用链表中DPC对象的延迟函数,直到链表为空。
  2. 通过KeInsertQueueDpc 插入DPC对象时。
  3. 在各个处理器的空闲线程中,如果发现有DPC对象尚未被执行,则交付这些DPC对象。

DPC流程,如图:

Windows内核与原理读书笔记之DPC和时钟中断和定时器管理

 

 

2.时钟中断和定时器管理

Windows 中最底层的定时器机制时通过时钟中断加上DPC对象来实现的。

系统中所有的定时器构成了一个链表数组,全局数组KiTimerTableListHead 包含了512个定时器链表,每个链表都有一个时间值,链表中的定时器为KTIMER对象。相关定义如下:

#define TIMER_TABLE_SIZE 512

typedef struct _KTIMER_TABLE_ENTRY {

    LIST_ENTRY Entry;

    ULARGE_INTEGER Time;

} KTIMER_TABLE_ENTRY, *PKTIMER_TABLE_ENTRY;

extern DECLSPEC_CACHEALIGN KTIMER_TABLE_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE];

typedef struct _KTIMER {

    DISPATCHER_HEADER Header;

    ULARGE_INTEGER DueTime;

    LIST_ENTRY TimerListEntry;

    struct _KDPC *Dpc;

    LONG Period;

} KTIMER, *PKTIMER, *PRKTIMER;

DueTime :指定的到期时间

Windows的定时器管理结构,如图:

Windows内核与原理读书笔记之DPC和时钟中断和定时器管理