Программирование драйверов Windows

         

Исполнительские ресурсы


Еще одним объектом, служащим для целей синхронизации, который весьма похож на мьютекс режима ядра, является так называемый исполнительский ресурс (executive resource). Такой объект может находиться в исключительном владении одного потока, либо используется совместно несколькими потоками только для операций чтения. Объекты исполнительских ресурсов обеспечивают лучшую производительность, чем стандартные мьютексы ядра.

Исполнительский ресурс является объектом типа ERESOURCE (с закрытыми для разработчика полями &#8212 в том смысле, что он не должен их использовать непосредственно из своего кода) и применяется для синхронизации доступа к одному или нескольким элементам данных. Любой код, прикасающийся к этим данным, должен сначала сделать запрос на владение соответствующим объектом ERESOURCE.

Если открыть определение структуры ERESOURCE в файле, например, wdm.h, то несложно понять, что исключительный доступ к данным, охраняемым объектом типа ERESOURCE, реализуется через механизм спин-блокировок.

Для работы с исполнительскими ресурсами используются вызовы, описанные в таблице 10.47. Как и быстрые мьютексы, эти объекты имеют собственные вызовы для запроса на владение, а не вызовы KeWaitForXxx. Разумеется, перед получением доступа следует выделить память под структуру ERESOURCE в нестраничной памяти и инициализировать ее при помощи вызова ExInitializeResourceLite.

Таблица 10.47. Функции для работы с исполнительскими ресурсами



Действие Используемый вызов
Создание ExInitializeResourceLite
Запрос на владение ExAcquireResourceExclusiveLite

ExAcquireResourceSharedLite

ExTryToAcquireResourceExclusizeLite

ExConvertExclusizeToSharedLite

ExAcquireSharedStarveExclusive

ExAcquireSharedWaitForExclusive

Запрос состояния ExIsResourceAcquiredExclusiveLite

ExIsResourceAcquiredSharedLite

Освобождение ExReleaseResourceForThreadLite
Удаление ExDeleteResourceLite

Запросы на владение можно выполнять из кода, работающего на уровне IRQL ниже DISPATCH_LEVEL, все остальные вызовы можно делать и из кода работающего собственно на этом уровне.

Ре-инициализация исполнительского ресурса может быть выполнена вызовом ExReinitializeResourceLite, который заменяет сразу три вызова (по удалению ресурса, выделению памяти под новую структуру и инициализации) и экономит память.



Содержание раздела