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
_____
Modified: trunk/reactos/drivers/net/ndis/ndis/control.c
--- trunk/reactos/drivers/net/ndis/ndis/control.c 2005-08-24
12:20:59 UTC (rev 17510)
+++ trunk/reactos/drivers/net/ndis/ndis/control.c 2005-08-24
12:21:18 UTC (rev 17511)
@@ -14,10 +14,29 @@
/*
- * @unimplemented
+ * @implemented
*/
VOID
EXPORT
+NdisInitializeReadWriteLock(
+ IN PNDIS_RW_LOCK Lock)
+/*
+ * FUNCTION: Initialize a NDIS_RW_LOCK
+ * ARGUMENTS:
+ * Lock: pointer to the lock to initialize
+ * NOTES:
+ * NDIS 5.0
+ */
+{
+ RtlZeroMemory(Lock, sizeof(NDIS_RW_LOCK));
+}
+
+
+/*
+ * @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;
+ }
+}
+
+
+/*
+ * @implemented
+ */
#undef NdisAcquireSpinLock
VOID
EXPORT
_____
Modified: trunk/reactos/drivers/net/ndis/ndis/main.c
--- trunk/reactos/drivers/net/ndis/ndis/main.c 2005-08-24 12:20:59 UTC
(rev 17510)
+++ trunk/reactos/drivers/net/ndis/ndis/main.c 2005-08-24 12:21:18 UTC
(rev 17511)
@@ -97,25 +97,6 @@
/*
* @implemented
*/
-VOID
-EXPORT
-NdisInitializeReadWriteLock(
- IN PNDIS_RW_LOCK Lock)
-/*
- * FUNCTION: Initialize a NDIS_RW_LOCK
- * ARGUMENTS:
- * Lock: pointer to the lock to initialize
- * NOTES:
- * NDIS 5.0
- */
-{
- memset(Lock,0,sizeof(NDIS_RW_LOCK));
-}
-
-
-/*
- * @implemented
- */
NDIS_STATUS
EXPORT
NdisWriteEventLogEntry(
_____
Modified: trunk/reactos/drivers/net/ndis/ndis/stubs.c
--- trunk/reactos/drivers/net/ndis/ndis/stubs.c 2005-08-24 12:20:59 UTC
(rev 17510)
+++ trunk/reactos/drivers/net/ndis/ndis/stubs.c 2005-08-24 12:21:18 UTC
(rev 17511)
@@ -857,24 +857,6 @@
/*
* @unimplemented
*/
-VOID
-EXPORT
-NdisReleaseReadWriteLock(
- IN PNDIS_RW_LOCK Lock,
- IN PLOCK_STATE LockState)
-/*
- * FUNCTION:
- * ARGUMENTS:
- * NOTES:
- * NDIS 5.0
- */
-{
- UNIMPLEMENTED
-}
-
-/*
- * @unimplemented
- */
ULONG
EXPORT
NdisWritePcmciaAttributeMemory(
Show replies by date