Функция NdisAllocateSpinLock (ndis.h)
Функция NdisAllocateSpinLock инициализирует переменную типа NDIS_SPIN_LOCK, используемую для синхронизации доступа к ресурсам, совместно используемым функциями драйверов, не относящихся к ISR.
Синтаксис
void NdisAllocateSpinLock(
[out] PNDIS_SPIN_LOCK SpinLock
);
Параметры
[out] SpinLock
Указатель на непрозрачную переменную, представляющую блокировку спина.
Возвращаемое значение
None
Remarks
Прежде чем драйвер вызывает NdisAcquireSpinLock, NdisDprAcquireSpinLock или любую из функций NdisInterlockedXxx , он должен вызвать NdisAllocateSpinLock , чтобы инициализировать блокировку спина, переданную в качестве обязательного параметра для этих функций NdisXxx . Вызывающий объект должен предоставить непагрегированное хранилище для переменной в SpinLock .
После вызова NdisAllocateSpinLock драйвер может вызвать NdisAcquireSpinLock , чтобы получить монопольное использование ресурсов, защищаемых спин-блокировкой. После завершения доступа к ресурсам драйвер вызывает NdisReleaseSpinLock , чтобы другие функции драйвера могли получить доступ к ресурсам, защищенным этой блокировкой спина.
Как правило, для повышения производительности драйвер должен использовать различные блокировки для защиты разных критически важных разделов. Таким образом, драйвер может инициализировать несколько спиновых блокировок с помощью NdisAllocateSpinLock.
Каждая блокировка спина, выделяемая драйвером, защищает дискретный набор общих ресурсов от одновременного доступа функций драйвера, которые выполняются в IRQL <= DISPATCH_LEVEL. Например, драйвер, поддерживающий внутреннюю очередь пакетов, может инициализировать одну блокировку спина для защиты очереди, а другую — для защиты набора переменных состояния, которые выполняют несколько функций драйвера, не включая MiniportInterrupt илиФункция MiniportDisableInterruptEx— доступ, пока драйвер обрабатывает пакеты.
NdisAcquireSpinLock вызывает IRQL для DISPATCH_LEVEL и сохраняет старый IRQL в спин-блокировке. При освобождении блокировки спина в irQL устанавливается значение, хранящееся в спин-блокировке. Так как NDIS иногда входит в драйверы в PASSIVE_LEVEL, могут возникнуть проблемы со следующим кодом:
NdisAcquireSpinLock(A);
NdisAcquireSpinLock(B);
NdisReleaseSpinLock(A);
NdisReleaseSpinLock(B);
Драйвер не должен получать доступ к блокировкам спина в этой последовательности по следующим причинам:
- Между NdisReleaseSpinLock(A) и NdisReleaseSpinLock(B) код выполняется на PASSIVE_LEVEL вместо DISPATCH_LEVEL и может быть неправильно прерван.
- После NdisReleaseSpinLock(B) код выполняется в DISPATCH_LEVEL что может привести к сбою вызывающего объекта гораздо позже с ошибкой IRQL_NOT_LESS_OR_EQUAL stop.
Драйвер мини-порта не может использовать спиновую блокировку для защиты ресурсов, которые его функции, не относящиеся к ISR, совместно используются с miniportInterrupt илиФункция MiniportDisableInterruptEx. Для доступа к ресурсам, совместно используемым с помощью функции MiniportInterrupt или MiniportDisableInterruptEx , драйвер мини-порта должен вызвать NdisMSynchronizeWithInterruptEx , чтобы иметь свой Функция MiniportSynchronizeInterrupt обращается к этим ресурсам в DIRQL.
Если драйверу больше не требуется защита ресурсов, например когда сетевой адаптер удаляется и драйвер освобождает ресурсы, выделенные для этой сетевой карты, драйвер вызывает NdisFreeSpinLock.
Освобождение спиновой блокировки и освобождение спин-блокировки могут быть запутанными. NdisFreeSpinLock очищает память в SpinLock , чтобы она больше не представляла спиновую блокировку. Освобождение полученной спиновой блокировки с помощью NdisReleaseSpinLock просто позволяет другому потоку выполнения получить ее.
Дополнительные сведения о получении и освобождении спиновых блокировок NDIS см. в статье Синхронизация и уведомление в сетевых драйверах.
Вызывающие функции NdisAllocateSpinLock могут выполняться в любом irQL. Обычно вызывающий объект выполняется в irQL = PASSIVE_LEVEL во время инициализации.
Требования
Требование | Значение |
---|---|
Минимальная версия клиента | Поддерживается для драйверов NDIS 6.0 и NDIS 5.1 (см. раздел NdisAllocateSpinLock (NDIS 5.1)) в Windows Vista. Поддерживается для драйверов NDIS 5.1 (см. раздел NdisAllocateSpinLock (NDIS 5.1)) в Windows XP. |
Целевая платформа | Универсальное |
Верхняя часть | ndis.h (включая Ndis.h) |
Библиотека | Ndis.lib |
IRQL | Любой уровень (см. раздел "Примечания") |
Правила соответствия DDI | SpinLockDpr(ndis), SpinLockDprRelease(ndis), SpinlockRelease(ndis) |
См. также раздел
DriverEntry of NDIS Protocol Drivers
NdisInterlockedInsertHeadList NdisInterlockedInsertTailList NdisInterlockedRemoveHeadList NdisMSynchronizeWithInterruptEx