Some constants for the magic numbers would be nice.
________________________________________
From: ros-diffs-bounces(a)reactos.com [mailto:ros-diffs-bounces@reactos.com] On Behalf Of
navaraf(a)svn.reactos.com
Sent: 24. august 2005 14:21
To: ros-diffs(a)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;
+ }
+}
+
+