Поделиться через


Функция NdisAllocateSpinLock (ndis.h)

Функция NdisAllocateSpinLock инициализирует переменную типа NDIS_SPIN_LOCK, используемую для синхронизации доступа к ресурсам, общим для функций драйвера, отличных от ISR.

Синтаксис

void NdisAllocateSpinLock(
  [out] PNDIS_SPIN_LOCK SpinLock
);

Параметры

[out] SpinLock

Указатель на непрозрачную переменную, представляющую блокировку спина.

Возвращаемое значение

Никакой

Замечания

Перед вызовом драйвера NdisAcquireSpinLock, NdisDprAcquireSpinLockили любой из функций NdisInterlockXxx, он должен вызывать 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 иметь его 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 (include 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