“An exception to the rule that raising the IRQL blocks interrupts of that level and
lower relates to APC-level interrupts. If a thread raises the IRQL to APC level and then
is rescheduled because of a dispatch/DPC-level interrupt, the system might deliver an
APC-level interrupt to the newly scheduled thread. Thus, APC level can be considered a
thread-local rather than processor-wide IRQL.”
Can somebody explain this exception? If a thread raises the IRQL to APC level and then
is rescheduled because of a dispatch/DPC-level interrupt…
there are mainly two reasons for a thread preemption to occur:
(1) the thread enters a wait state,
(2) its time quatrum expires.
As for (1), after the thread enters a wait state (because it calls some
of the KeWaitXXX functions, KeDelayExecutionThread etc.), the system
schedules a new thread to run on the processor. AFAIK the scheduling
code itself runs at IRQL = DISPATCH_LEVEL which is higher tnan
APC_LEVEL, so no rule is violated here. I am not sure how the scheduling
is actually implemented but I believe when the IRQL drops below
DISPATCH_LEVEL (as a result of releasing locks needed to perform the
scheduling), the context is set to the newly scheduled thread.
The (2) case is detected inside a timer interrupt that runs at IRQL >
DISPATCH_LEVEL. I think the scheduling itself is performed through a DPC
targetted to the processor on which the expired thread runs. And DPCs
are executed at IRQL = DISPATCH_LEVEL (excluding Threaded DPCs from this
case). So the IRQL rule is actually not violated.
“An exception to the rule that raising the IRQL blocks interrupts of that level and
lower relates to APC-level interrupts. If a thread raises the IRQL to APC level and then
is rescheduled because of a dispatch/DPC-level interrupt, the system might deliver an
APC-level interrupt to the newly scheduled thread. Thus, APC level can be considered a
thread-local rather than processor-wide IRQL.”
Can somebody explain this exception? If a thread raises the IRQL to APC level and then
is rescheduled because of a dispatch/DPC-level interrupt…
DISPATCH_LEVEL and above are not part of a thread state. They are associated with a processor. When you run on DISPATCH_LEVEL and above, the thread switch cannot occur, thus while you run on such IRQL, you’re on a given processor, and the processor only runs the given thread.
When you run on <=APC_LEVEL, the thread can get rescheduled. APC_LEVEL is set as part of thread context and always goes with the thread, to whichever processor it’s scheduled to run.
Basically, by means of IRQL mechanism Windows implements 2 totally unrelated general SC concepts,namely, the notion of disabled signal delivery and the one of atomic context, which happens to be a never-ending source of confusion for Windos newbies.
IRQL==APC_LEVEL means that signals (known as APC under Windows) are not going to be delivered
to currently running thread. However, context switches still may occur because scheduler is not disabled at APC level, and,hence, the target thread is allowed to make blocking calls.
IRQL > APC_LEVEL means that the code runs in atomic context, i.e dispatcher is disabled and blocking calls are not allowed…