Some constants for the magic numbers would be nice.
________________________________________ From: ros-diffs-bounces@reactos.com [mailto:ros-diffs-bounces@reactos.com] On Behalf Of navaraf@svn.reactos.com Sent: 24. august 2005 14:21 To: ros-diffs@reactos.com Subject: [ros-diffs] [navaraf] 17511: Implement the most over-optimized lockin NT - the NDIS_RW_LOCK.
Implement the most over-optimized lock in NT - the NDIS_RW_LOCK. Modified: trunk/reactos/drivers/net/ndis/ndis/control.c Modified: trunk/reactos/drivers/net/ndis/ndis/main.c Modified: trunk/reactos/drivers/net/ndis/ndis/stubs.c
+/* + * @implemented + */ +VOID +EXPORT NdisAcquireReadWriteLock( IN PNDIS_RW_LOCK Lock, IN BOOLEAN fWrite, @@ -29,13 +48,88 @@ * NDIS 5.0 */ { - UNIMPLEMENTED + ULONG RefCount; + UCHAR ProcessorNumber; + UCHAR BusyLoop; + + ASSERT_IRQL(DISPATCH_LEVEL); + + if (fWrite) { + if (Lock->Context == PsGetCurrentThread()) { + LockState->LockState = 2; + } else { + KeAcquireSpinLock(&Lock->SpinLock, &LockState->OldIrql); + /* Check if any other processor helds a shared lock. */ + for (ProcessorNumber = KeNumberProcessors; ProcessorNumber--; ) { + if (ProcessorNumber != KeGetCurrentProcessorNumber()) { + /* Wait till the shared lock is released. */ + while (Lock->RefCount[ProcessorNumber].RefCount != 0) { + for (BusyLoop = 32; BusyLoop--; ) + ; + } + } + } + Lock->Context = PsGetCurrentThread(); + LockState->LockState = 4; + } + } else { + KeRaiseIrql(DISPATCH_LEVEL, &LockState->OldIrql); + RefCount = InterlockedIncrement((PLONG)&Lock->RefCount[KeGetCurrentProcessorNumber()].RefCount); + /* Racing with a exclusive write lock case. */ + if (Lock->SpinLock != 0) { + if (RefCount == 1) { + if (Lock->Context != PsGetCurrentThread()) { + /* Wait for the exclusive lock to be released. */ + Lock->RefCount[KeGetCurrentProcessorNumber()].RefCount--; + KefAcquireSpinLockAtDpcLevel(&Lock->SpinLock); + Lock->RefCount[KeGetCurrentProcessorNumber()].RefCount++; + KefReleaseSpinLockFromDpcLevel(&Lock->SpinLock); + } + } + } + LockState->LockState = 3; + } }
/* * @implemented */ +VOID +EXPORT +NdisReleaseReadWriteLock( + IN PNDIS_RW_LOCK Lock, + IN PLOCK_STATE LockState) +/* + * FUNCTION: + * ARGUMENTS: + * NOTES: + * NDIS 5.0 + */ +{ + switch (LockState->LockState) { + case 2: /* Exclusive write lock, recursive */ + return; + + case 3: /* Shared read lock */ + Lock->RefCount[KeGetCurrentProcessorNumber()].RefCount--; + LockState->LockState = -1; + if (LockState->OldIrql < DISPATCH_LEVEL) + KeLowerIrql(LockState->OldIrql); + return; + + case 4: /* Exclusive write lock */ + Lock->Context = NULL; + LockState->LockState = -1; + KfReleaseSpinLock(&Lock->SpinLock, LockState->OldIrql); + return; + } +} + +