windows核心原理分析之DPC函式的執行(1)
windows核心原理分析之DPC函式的執行(1)
當發生中斷時,有些操作本來應該在中斷服務程式中完成,但是實際上卻是在退出中斷服務程式之後在一個DPC函式中完成的。DPC是”Deferred Procedure Call”的縮寫,意為推遲了的過程(函式)呼叫。這是因為,邏輯上應該放在中斷服務程式中完成的操作並非都是那麼緊迫,其中有一部分可能相對而言不那麼緊迫,而又比較費時間,實際上可以放在開中斷的條件下執行。如果把這些操作都放在中斷服務程式中,就會使關閉中斷的時間太長而引起中斷請求的丟失,因為整個中斷服務程式通常都是在關中斷的條件下執行的。為此,把中斷服務程式中不那麼緊迫卻比較費時,而又不必在關中斷條件下執行的操作分割出來,放在另一個函式中,在開中斷的條件下加以執行,就可以縮短關中斷的時間。這樣的函式就是DPC函式。一般而言,中斷服務前期的操作是比較緊迫的,並且是必須關中斷的,此時可以很快地對外部裝置進行操作。此後,剩下的那部分操作便可以稍後在開中斷的條件下執行。所以有人曾經把這部分操作稱為中斷服務的”後半(Bottom Half)”,也有人把這兩半分別稱為”硬中斷”和”軟中斷”。之所以要把中斷服務分成前後兩半,是因為一次中斷服務的後半不如另一次中斷的前半那麼緊迫。
為此,核心中要有個DPC請求佇列,中斷服務程式執行完它的”前半”之後就把一個DPC請求掛入這個佇列,要求核心呼叫相應的DPC函式,然後(形式上)就從中斷返回了。接著,如果沒有別的中斷請求,核心就會掃描這個DPC請求佇列,依次在開中斷的條件下執行這些DPC函式,直至又發生中斷或執行完佇列中的所有DPC函式。至於當前執行緒所要執行的程式,則只有在DPC請求佇列為空的時候才會繼續得到執行。顯然,這裡所體現的是”急事急辦”的原則,中斷是最急的,DPC函式其次,最後才是當前執行緒。Windows核心的IRQL(即執行級別)就反映了這些活動的輕重緩急,DPC函式是在DISPATCH_LEVEL級別上執行的。
與DPC函式的執行有關的另一個問題是堆疊的使用。我們知道,中斷服務程式所使用的堆疊就是當前執行緒的系統空間堆疊。中斷服務程式一般都是比較輕小的,佔用一下當前執行緒的堆疊不至於會有問題;但是DPC函式就不同了,DPC函式有可能是比較大的,如果仍舊佔用當前執行緒的堆疊,在最壞的情況下有可能造成堆疊溢位,所以最好是為DPC函式的執行另外配備一個堆疊。
Windows核心把DPC請求佇列放在每個CPU的PRCB資料結構中。此外,PRCB結構中還有一些別的與DPC有關的欄位:
typedef struct _KPRCB
{
......
ULONG DpcTime;
ULONG DebugDpcTime;
ULONG InterruptTime;
ULONG AdjustDpcThreshold;
......
struct _KDPC_DATA DpcData[2]; //兩個DPC請求佇列
PVOID DpcStack;
ULONG MaximumDpcQueueDepth;
ULONG DpcRequestRate;
ULONG MinimumDpcRate;
volatile UCHAR DpcInterruptRequested;
volatile UCHAR DpcThreadRequested;
volatile UCHAR DpcRoutineActive;
volatile UCHAR DpcThreadActive;
ULONG PrcbLock;
ULONG DpcLastCount;
......
PVOID DpcThread;
KEVENT DpcEvent;
UCHAR ThreadDpcEnable;
......
LONG DpcSetEventRequest;
......
KDPC CallDpc;
......
} KPRCB, *PKPRCB;
其中的DpcData[2]是大小為2的_KDPC_DATA結構陣列,其結構定義如下:
typedef struct _KDPC_DATA
{
LIST_ENTRY DpcListHead; //用於DPC請求佇列的佇列頭
ULONG DpcLock;
volatile ULONG DpcQueueDepth;
ULONG DpcCount;
} KDPC_DATA, *PKDPC_DATA;
可見,每個_KDPC_DATA結構中都有個佇列頭,這就是用於DPC請求佇列的。
DpcData[]的大小為2,說明有兩個DPC請求佇列,它們是:
#define DPC_NORMAL 0
#define DPC_THREADED 1
顯然,其中之一是”常規”的DPC請求佇列,另一個是”執行緒化”的DPC請求佇列。目前ReactOS已經實現的是常規DPC請求。
裝置物件的資料結構DEVICE_OBJECT中有個成分Dpc,這是個KDPC資料結構,用來設定有關本裝置物件的DPC函式的資訊:
typedef struct _KDPC
{
UCHAR Type; //DpcObject或ThreadedDpcObject
UCHAR Importance; //緊迫程度
USHORT Number; //CPU號碼(在多處理器系統中)
LIST_ENTRY DpcListEntry; //用來掛入DPC請求佇列
PKDEFERRED_ROUTINE DeferredRoutine; //指向具體的DPC函式
PVOID DeferredContext; //執行DPC函式時的上下文
PVOID SystemArgument1; //執行DPC函式時的引數
PVOID SystemArgument2;
volatile PVOID DpcData; //指向所掛入的KDPC_DATA結構
} KDPC, *PKDPC, *RESTRICTED_POINTER PRKDPC;
裝置物件在初始化時通過KeInitializeDpc()設定好它的KDPC資料結構。
VOID NTAPI
KeInitializeThreadedDpc(IN PKDPC Dpc, IN
PKDEFERRED_ROUTINE DeferredRoutine,
IN PVOID DeferredContext)
{
/* Call the internal routine */
KiInitializeDpc(Dpc, DeferredRoutine, DeferredContext,
ThreadedDpcObject);
}
VOID NTAPI
KiInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine,
IN PVOID DeferredContext, IN KOBJECTS Type)
{
/* Setup the DPC Object */
Dpc->TypeType = Type;
Dpc->Number = 0;
Dpc->Importance= MediumImportance;
Dpc->DeferredRoutineDeferredRoutine = DeferredRoutine;
Dpc->DeferredContextDeferredContext = DeferredContext;
Dpc->DpcData = NULL;
}
相關文章
- js立即執行函式原理JS函式
- 1.自執行函式表示式函式
- python效能優化之函式執行時間分析Python優化函式
- (未完成)APC函式的執行,分析 KiDeliverApc 函式函式IDE
- windows核心程式設計--windows程式的執行Windows程式設計
- Spring核心原理分析之MVC九大元件(1)SpringMVC元件
- js封裝函式來 解釋jQuery的執行原理JS封裝函式jQuery
- browserify執行原理分析
- Locust 執行原理分析
- Oracle分析函式-1Oracle函式
- Windows核心執行體物件管理器的操作過程與分析Windows物件
- Java 執行緒池執行原理分析Java執行緒
- python之為函式執行設定超時時間(允許函式執行的最大時間)Python函式
- 自執行函式函式
- 立即執行函式函式
- 自執行函式的理解函式
- Java執行緒池核心原理剖析Java執行緒
- 執行緒池核心原理淺析執行緒
- 【Analytic】分析函式之MIN函式函式
- 【Analytic】分析函式之MAX函式函式
- 【Analytic】分析函式之AVG函式函式
- 【Analytic】分析函式之RANK函式函式
- 【Analytic】分析函式之COUNT函式函式
- 【分析函式】Oracle分析函式之LAG和LEAD函式Oracle
- 函式節流、函式防抖實現原理分析函式
- JavaScript入門③-函式(2)原理{深入}執行上下文JavaScript函式
- 正規表示式exec()函式只有第一執行有效分析函式
- php底層原理之函式PHP函式
- javascript中的自執行(立即執行)函式(function(){…})()JavaScript函式Function
- mysql之常用函式(核心總結)MySql函式
- 多執行緒核心技術(1)-執行緒的基本方法執行緒
- JavaScript中的立即執行函式JavaScript函式
- 常見函式之單行函式函式
- 核心堆分配函式brk()原始碼分析函式原始碼
- jmeter之GUI執行原理JMeterGUI
- 深入理解 函式、匿名函式、自執行匿名函式函式
- Java面試必問之執行緒池的建立使用、執行緒池的核心引數、執行緒池的底層工作原理Java面試執行緒
- WINDOWS未開函式揭密(1) (轉)Windows函式