Функция 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 остановки.
Драйвер никогда не должен использовать две спин-блокировки для защиты одного и того же (под)набора ресурсов, так как вложенные покупки спин-блокировок так часто вызывают взаимоблокировки. Даже если драйвер может быть разработан для предотвращения взаимоблокировок, вложенные покупки спин-блокировок оказывают негативное влияние на производительность драйвера и пропускную способность ввода-вывода.

Минипорт-драйвер не может использовать спин-блокировку для защиты ресурсов, которыми совместно используются функции, отличные от ISR, с функцией MiniportInterrupt или MiniportDisableInterruptEx . Чтобы получить доступ к ресурсам, к которым предоставлен доступ с функцией MiniportInterrupt или MiniportDisableInterruptEx, драйвер минипорта должен вызвать NdisMSynchronizeWithInterruptEx для доступа к этим ресурсам в 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 драйверов протокола NDIS

MiniportDisableInterruptEx

MiniportHaltEx

MiniportInitializeEx

MiniportInterrupt

NdisAcquireSpinLock

NdisDprAcquireSpinLock

NdisDprReleaseSpinLock

NdisFreeSpinLock

NdisInterlockedAddUlong

NdisInterlockedInsertHeadList

NdisInterlockedInsertTailList

NdisInterlockedRemoveHeadList

NdisMSynchronizeWithInterruptEx

NdisReleaseSpinLock

NetTimerCallback