完整投影片下載: ppt
預計閱讀時間: 15 分鐘
重點:
1.由於 Scheduler 執行在 DISPATCH_LEVEL:
1.任何在 dispatch
以上(包含) 的 activity
都無法享受 time-sharing 多工的服務 ( “不” 可以被切換工作)
2.任何在 dispatch
以下的 activity
都可以享受
time-sharing 多工的服務
2.由於 Page fault 處理執行在 APC_LEVEL:
1.任何在 apc 以上(包含) 的 activity 都 “無法” 享受完整的
virtual memory (only non-paged memory) 服務
2.在 passive
level 的 activity
可以使用完整的 virtual
memory 服務
3.執行在 DISPATCH
level 以上 (包含) 的 activity,
既不能被插斷, 也沒有完整的 virtual
memory 服務可使用
Fig. Interrupt Priority in Action
兩個中斷與一個 DPC搭配 IRQL 的例子
重點:
- 事件 3: 中斷 1 正在執行時, 中斷 2 來了. 但因為中斷 2 的 DIRQL 比較低, 所以 CPU 不受影響. 依然執行 中斷 1 的服務常式
- 事件 4: 中斷 1 執行完畢後, 發出 一個 DPC request 要求系統繼續後面還沒完成的工作. 這時候, CPU 到底要決定執行 中斷1 的 DPC 還是 中斷 2 的 service routine? è 由於 所有的 DPC 都在 DISPATCH level 執行, 而中斷 2 的 DIRQ 比 DISPATCH 高, 所以 CPU 執行中斷 2 的服務常式
重點:
Q: 為什麼
caller 必須在 DISPATCH_LEVL
以下?
è KeWaitForSingleObject 等待的時間中, thread 會被 block 住. 我們使用 WaitForSingleObject 時, 通常是希望等某個事件完成後, 再繼續執行後續的工作.
但在 driver 中, 你呼叫 KeWaitForSingleObject() 的 thread
必須在 IRQL
< DISPATCH_LEVEL 的情況下, 這樣才能讓 preempt
機制運作讓其他的 thread
執行插斷你的 blocking
thread, 去做其他的事情. (前面說過,
scheduler 在 DISPATCH_LEVEL
執行)
Q:
caller == DISPATCH_LEVEL 又怎樣?
è可想而知, 當 caller == DISPATCH_LEVEL 時, 你又呼叫 KeWaitForSingleObject(). 那整個系統中, 所有低於或等於
DISPATCH_LEVEL的 activities, 全部都不能動. 必須等你完成. 除非這時來了高於
DISPATCH_LEVEL 的 activity. 所以, 若你在 DISPATCH_LEVEL 時, 又呼叫 KeWaitForSingleObject() 的目的, 最好是 check
一下你等的 event 狀態 (是否 signaled). 因為系統中大部分的工作都被卡住, 等你一個. 這時候 wait 的時間最好不要太長, 這個 wait會嚴重影響系統的效能.
我們都知道 DPC 的 IRQL =DISPATCH_LEVEL, 所以你在 DPC 中是可以呼叫 KeWaitForSingleObject(), 但用法最好只是 check 某個 event 的狀態, 別期待其他 lower activities 或 DPC 會同步執行. 若你在目前的 DPC 中等這個 event, 而該 event 是其他的 DPC 才會 signal, 那很可能就會發生 deadlock 的情況發生.
我們都知道 DPC 的 IRQL =DISPATCH_LEVEL, 所以你在 DPC 中是可以呼叫 KeWaitForSingleObject(), 但用法最好只是 check 某個 event 的狀態, 別期待其他 lower activities 或 DPC 會同步執行. 若你在目前的 DPC 中等這個 event, 而該 event 是其他的 DPC 才會 signal, 那很可能就會發生 deadlock 的情況發生.
Q:
為何在 ISR
中,
不能呼叫 KeWaitForSingleObject?
è 因為 ISR 的 IRQ
> DISPATCH_LEVEL. Windows 限制任何高於 DISPATCH_LEVEL
的 activity
呼叫 KeWaitForSingleObject. 我猜其中原因就是: 高於 DISPATCH_LEVEL 的 activity
雖然可以被更高的 IRQL 中斷, 但會卡住大部分的作業系統功能 (因為 scheduler 不能動了). 如果在這種重要的功能中, 還等待的話. 那就會嚴重影響系統的效能. 所以 Windows 限制 呼叫
KeWaitForSingleObject() 只能在 <= DISPATCH_LEVEL 的 activities
中.
Enjoy!
by Jing.
Reference:
- Chapter 4, Synchronization, Programming the Microsoft Windows Driver Model, 2nd Ed.






