Dispatch level

DISPATCH LEVEL (в операционной системе Windows) — уровень приоритета (режим работы) потока, в котором приостановлена вытесняющая многозадачность.

Исполнение в этом режиме возможно только в ядре ОС, код пользовательского режима не имеет никаких способов исполняться в этом режиме.

Уровень DISPATCH, как и более низкие уровни приоритета (APC и PASSIVE), не связан с аппаратными режимами процессора, и обеспечивается только программными средствами.

Этот уровень используется для выполнения действий, при которых недопустимо нарушение соответствия между текущим потоком и процессором (процессорным ядром) — как переключением процессора на другой поток, так и потока на другой процессор. В однопроцессорной системе это просто означает, что никакой код режима пользователя не будет выполнен до тех пор, пока уровень приоритета не будет понижен. В многопроцессорной системе это справедливо лишь для текущего процессора (ядра), но вдобавок гарантирует, что текущий поток не будет перемещен на другой процессор (ядро).

В частности, уровень DISPATCH используется при реализации блокировок типа Spin Lock. Если блокировка будет захвачена с сохранением вытесняющей многозадачности, то текущий поток может быть прерван в любой момент с переключением процессора на новый поток. Так как неизвестно, какие действия будет выполнять новый поток, есть возможность повторного захвата им того же Spin Lock'а, что приведет ко взаимной блокировке обоих потоков. Поскольку на повышенных уровнях приоритета выполняется только системный код, это с высокой вероятностью приводит к полной блокировке (зависанию) всей системы.

Чтобы избежать этого, ОС приостанавливает вытесняющую многозадачность перед захватом Spin Lock'а. Более того, в случае одного процессора этого вполне достаточно для обеспечения семантики захвата блокировки, собственно захват уже не нужен и не применяется в ядре ОС, построенном для одного процессора.

Запрет переключения потоков также позволяет избежать длительного выполнения цикла ожидания освобождения блокировки в многопроцессорной системе, который привел бы к непродуктивному использованию вычислительных ресурсов процессора. Повышение уровня приоритета гарантирует, что поток, захвативший блокировку на другом процессоре/ядре, может быть прерван лишь обработчиками прерываний, время работы которых не должно превышать нескольких десятков микросекунд.

Код, исполняемый на DISPATCH_LEVEL:

  • любой код, захватывающий и удерживающий Spin Lock
  • код, исполняемый в контексте DPC, в том числе обратные вызовы из нижележащих модулей и обработчики завершения ввода-вывода.
  • код, который необходимо исполнить только на текущем процессоре (ядре), если весь текущий поток не привязан к определенному процессору (ядру)

Ограничения на DISPATCH_LEVEL:

  • запрет KeWaitForSingleObject и любых других вызовов, приостанавливающих исполнение потока и отдающих управление другим потокам.
  • запрет доступа к любому выгружаемому коду и/или данным. Логически проистекает из предыдущего запрета, ибо разрешение отказа страницы включает в себя ожидание завершения дисковой операции чтения страницы.
  • следует также следить за ограничениями на уровень приоритета, приведенными в документации на конкретные API ядра ОС. Как правило, сутью таких ограничений является использование ожиданий или же выгружаемой памяти внутри реализаций этих вызовов.

Код, исполняемый на DISPATCH_LEVEL, по-прежнему может быть прерван любым прерыванием, хотя и с гарантией, что прерывание не приведет к смене текущего потока. В случае необходимости синхронизации доступа к данным и регистрам аппаратуры, используемым и из прерывания, и из иного кода — необходимо использовать блокировку, связанную с прерыванием, то есть KeSynchronizeExecution или KeAcquireInterruptSpinLock. Пользоваться обычными блокировками в этой ситуации, как и в самих обработчиках прерываний, запрещено.

Примерным аналогом в Linux является «код, который не может быть заблокирован» (cannot block). Правило Linux о том, что код, владеющий spinlock, не может блокироваться — полностью аналогично соответствующему правилу в Windows.

Литература править

  • М. Руссинович, Д. Соломон. 1 // Внутреннее устройство Microsoft Windows. — 6-е изд.. — СПб.: Питер, 2013. — С. 217—220. — 800 с. — ("Мастер-класс"). — ISBN 978-5-459-01730-4.
  • Уолтер Они. Использование Microsoft Windows Driver Model. — 2-е изд.. — СПб.: Питер, 2007. — С. 166—177. — 764 с. — ISBN 978-5-91180-057-4.
  • Understanding Архивная копия от 8 декабря 2017 на Wayback Machine IRQL.