- DISPATCH LEVEL
-
В данной статье или разделе имеется список источников или внешних ссылок, но источники отдельных утверждений остаются неясными из-за отсутствия сносок. Вы можете улучшить статью, внеся более точные указания на источники.В операционной системе Windows режим работы процессора, в котором приостановлена вытесняющая многозадачность.
Исполнение в этом режиме возможно только в ядре ОС, код пользовательского режима не имеет никаких способов исполняться в этом режиме.
Архитектурная необходимость в таком режиме проистекает из наличия блокировок (spinlocks). Если блокировка будет захвачена с сохранением вытесняющей многозадачности, то текущий поток может быть прерван в любой момент с переключением процессора на новый поток. Так как нет никаких гарантий на тему того, чем будет заниматься новый поток, есть возможность повторного захвата им того же spinlockа, что немедленно приводит к зависанию процессора.
Потому ОС приостанавливает вытесняющую многозадачность перед захватом блокировки. Более того, в случае одного процессора этого вполне достаточно для семантики захвата блокировки, собственно захват уже не нужен и не применяется в ядре ОС, построенном для одного процессора.
Код, исполняемый на DISPATCH_LEVEL:
- любой код, захватывающий и удерживающий spinlock
- код, исполняемый в контексте DPC, в том числе обратные вызовы из нижележащих модулей и обработчики завершения ввода/вывода.
Ограничения на DISPATCH_LEVEL:
- запрет KeWaitForSingleObject и любых других вызовов, приостанавливающих исполнение потока и отдающих управление другим потокам.
- запрет прикасаться к любому отгружаемому коду и/или данным. Логически проистекает из предыдущего запрета, ибо разрешение отказа страницы включает в себя ожидание завершения дисковой операции чтения страницы.
- следует также следить за ограничениями на уровень исполнения, приведенными в документации на конкретные API ядра ОС. Как правило, сутью таких ограничений является использование ожиданий или же отгружаемой памяти внутри реализаций этих вызовов.
Код, исполняемый на DISPATCH_LEVEL, по-прежнему может быть прерван любым прерыванием, хотя и с гарантией, что прерывание не приведет к смене текущего потока. В случае необходимости синхронизации доступа к данным и регистрам аппаратуры, используемым и из прерывания, и из иного кода — необходимо использовать блокировку, связанную с прерыванием, то есть KeSynchronizeExecution или KeAcquireInterruptSpinLock. Пользоваться обычными блокировками в этой ситуации, как и в самих обработчиках прерываний, запрещено.
Примерным аналогом в Linux является «код, не могущий блокироваться» (cannot block). Правило Linux о том, что код, владеюший spinlock, не может блокироваться — полностью аналогично соответствующему правилу в Windows.
Источники
Категория:- Microsoft Windows
Wikimedia Foundation. 2010.