Author: fireball
Date: Tue Apr 1 13:14:01 2008
New Revision: 32809
URL: http://svn.reactos.org/svn/reactos?rev=32809&view=rev
Log:
- Use C define for the bit in the wait block flags that we set to specify waiting, instead of a hardcoded "1".
- Fix broken code when trying to find the last wait block in several parts of the pushlock code.
- Fix broken algorithm in the optimization of the pushlock waiter list.
- The wake event for the pushlock should be a synchronization event, not a notification event.
- Fix broken algorithm during the release of a pushlock (in shared cases).
- Fix broken code during "try to wake pushlock".
- Remove DbgPrints from inlined pushlock code during contention.
- Thanks to Alex for noticing these bugs and providing advice on the fixes. This fixes lots of race issues in the handle table implementation.
Modified:
trunk/reactos/include/ndk/extypes.h
trunk/reactos/ntoskrnl/ex/pushlock.c (contents, props changed)
trunk/reactos/ntoskrnl/include/internal/ex.h
Modified: trunk/reactos/include/ndk/extypes.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/extypes.h?rev=…
==============================================================================
--- trunk/reactos/include/ndk/extypes.h [iso-8859-1] (original)
+++ trunk/reactos/include/ndk/extypes.h [iso-8859-1] Tue Apr 1 13:14:01 2008
@@ -147,6 +147,7 @@
// Pushlock Wait Block Flags
//
#define EX_PUSH_LOCK_FLAGS_EXCLUSIVE 1
+#define EX_PUSH_LOCK_FLAGS_WAIT_V 1
#define EX_PUSH_LOCK_FLAGS_WAIT 2
//
Modified: trunk/reactos/ntoskrnl/ex/pushlock.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/pushlock.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/pushlock.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ex/pushlock.c [iso-8859-1] Tue Apr 1 13:14:01 2008
@@ -65,7 +65,7 @@
EX_PUSH_LOCK OldValue)
{
EX_PUSH_LOCK NewValue;
- PEX_PUSH_LOCK_WAIT_BLOCK PreviousWaitBlock, FirstWaitBlock, NextWaitBlock;
+ PEX_PUSH_LOCK_WAIT_BLOCK PreviousWaitBlock, FirstWaitBlock, LastWaitBlock;
PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock;
KIRQL OldIrql;
@@ -99,23 +99,30 @@
/* Save the First Block */
FirstWaitBlock = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR)OldValue.Ptr &
~EX_PUSH_LOCK_PTR_BITS);
- NextWaitBlock = FirstWaitBlock;
- WaitBlock = NextWaitBlock->Last;
-
- /* Try to find a wait block */
- while (!WaitBlock)
- {
+ WaitBlock = FirstWaitBlock;
+
+ /* Try to find the last block */
+ while (TRUE)
+ {
+ /* Get the last wait block */
+ LastWaitBlock = WaitBlock->Last;
+
+ /* Check if we found it */
+ if (LastWaitBlock)
+ {
+ /* Use it */
+ WaitBlock = LastWaitBlock;
+ break;
+ }
+
/* Save the previous block */
- PreviousWaitBlock = NextWaitBlock;
+ PreviousWaitBlock = WaitBlock;
/* Move to next block */
- NextWaitBlock = NextWaitBlock->Next;
+ WaitBlock = WaitBlock->Next;
/* Save the previous block */
- NextWaitBlock->Previous = PreviousWaitBlock;
-
- /* Move to the next one */
- WaitBlock = NextWaitBlock->Last;
+ WaitBlock->Previous = PreviousWaitBlock;
}
/* Check if the last Wait Block is not Exclusive or if it's the only one */
@@ -211,58 +218,65 @@
ExpOptimizePushLockList(PEX_PUSH_LOCK PushLock,
EX_PUSH_LOCK OldValue)
{
- PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock, LastWaitBlock, PreviousWaitBlock;
+ PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock, LastWaitBlock, PreviousWaitBlock, FirstWaitBlock;
EX_PUSH_LOCK NewValue;
- /* Check if the pushlock is locked */
- if (OldValue.Locked)
- {
- /* Start main loop */
- for (;;)
- {
- /* Get the wait block */
- WaitBlock = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR)OldValue.Ptr &
- ~EX_PUSH_LOCK_PTR_BITS);
-
- /* Loop the blocks */
+ /* Start main loop */
+ for (;;)
+ {
+ /* Check if we've been unlocked */
+ if (!OldValue.Locked)
+ {
+ /* Wake us up and leave */
+ ExfWakePushLock(PushLock, OldValue);
+ break;
+ }
+
+ /* Get the wait block */
+ WaitBlock = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR)OldValue.Ptr &
+ ~EX_PUSH_LOCK_PTR_BITS);
+
+ /* Loop the blocks */
+ FirstWaitBlock = WaitBlock;
+ while (TRUE)
+ {
+ /* Get the last wait block */
LastWaitBlock = WaitBlock->Last;
- while (!LastWaitBlock)
- {
- /* Save the block */
- PreviousWaitBlock = WaitBlock;
-
- /* Get the next block */
- WaitBlock = WaitBlock->Next;
-
- /* Save the previous */
- WaitBlock->Previous = PreviousWaitBlock;
-
- /* Move to the next */
- LastWaitBlock = WaitBlock->Last;
- }
-
- /* Remove the wake bit */
- NewValue.Value = OldValue.Value &~ EX_PUSH_LOCK_WAKING;
-
- /* Sanity checks */
- ASSERT(NewValue.Locked);
- ASSERT(!NewValue.Waking);
-
- /* Update the value */
- NewValue.Ptr = InterlockedCompareExchangePointer(PushLock,
- NewValue.Ptr,
- OldValue.Ptr);
-
- /* If we updated correctly, leave */
- if (NewValue.Value == OldValue.Value) return;
-
- /* If the value is now locked, loop again */
- if (NewValue.Locked) continue;
- }
- }
-
- /* Wake the push lock */
- ExfWakePushLock(PushLock, OldValue);
+ if (LastWaitBlock)
+ {
+ /* Set this as the new last block, we're done */
+ FirstWaitBlock->Last = LastWaitBlock;
+ break;
+ }
+
+ /* Save the block */
+ PreviousWaitBlock = WaitBlock;
+
+ /* Get the next block */
+ WaitBlock = WaitBlock->Next;
+
+ /* Save the previous */
+ WaitBlock->Previous = PreviousWaitBlock;
+ }
+
+ /* Remove the wake bit */
+ NewValue.Value = OldValue.Value &~ EX_PUSH_LOCK_WAKING;
+
+ /* Sanity checks */
+ ASSERT(NewValue.Locked);
+ ASSERT(!NewValue.Waking);
+
+ /* Update the value */
+ NewValue.Ptr = InterlockedCompareExchangePointer(PushLock,
+ NewValue.Ptr,
+ OldValue.Ptr);
+
+ /* If we updated correctly, leave */
+ if (NewValue.Value == OldValue.Value) break;
+
+ /* Update value */
+ OldValue = NewValue;
+ }
}
/*++
@@ -297,7 +311,7 @@
/* Initialize the wait event */
KeInitializeEvent(&((PEX_PUSH_LOCK_WAIT_BLOCK)WaitBlock)->WakeEvent,
- NotificationEvent,
+ SynchronizationEvent,
FALSE);
/* Spin on the push lock if necessary */
@@ -320,7 +334,7 @@
/* Now try to remove the wait bit */
if (InterlockedBitTestAndReset(&((PEX_PUSH_LOCK_WAIT_BLOCK)WaitBlock)->Flags,
- 1))
+ EX_PUSH_LOCK_FLAGS_WAIT_V))
{
/* Nobody removed it already, let's do a full wait */
Status = KeWaitForSingleObject(&((PEX_PUSH_LOCK_WAIT_BLOCK)WaitBlock)->
@@ -766,18 +780,17 @@
FASTCALL
ExfReleasePushLock(PEX_PUSH_LOCK PushLock)
{
- EX_PUSH_LOCK OldValue = *PushLock;
- EX_PUSH_LOCK NewValue;
- PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock;
+ EX_PUSH_LOCK OldValue = *PushLock, NewValue, WakeValue;
+ PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock, LastWaitBlock;
/* Sanity check */
ASSERT(OldValue.Locked);
-
- /* Check if someone is waiting on the lock */
- if (!OldValue.Waiting)
- {
- /* Nobody is waiting on it, so we'll try a quick release */
- for (;;)
+
+ /* Start main loop */
+ while (TRUE)
+ {
+ /* Check if someone is waiting on the lock */
+ if (!OldValue.Waiting)
{
/* Check if it's shared */
if (OldValue.Shared > 1)
@@ -800,28 +813,179 @@
/* Did it enter a wait state? */
OldValue = NewValue;
- if (NewValue.Waiting) break;
- }
+ }
+ else
+ {
+ /* Ok, we do know someone is waiting on it. Are there more then one? */
+ if (OldValue.MultipleShared)
+ {
+ /* Get the wait block */
+ WaitBlock = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR)OldValue.Ptr &
+ ~EX_PUSH_LOCK_PTR_BITS);
+
+ /* Loop until we find the last wait block */
+ while (TRUE)
+ {
+ /* Get the last wait block */
+ LastWaitBlock = WaitBlock->Last;
+
+ /* Did it exist? */
+ if (LastWaitBlock)
+ {
+ /* Choose it */
+ WaitBlock = LastWaitBlock;
+ break;
+ }
+
+ /* Keep searching */
+ WaitBlock = WaitBlock->Next;
+ }
+
+ /* Make sure the Share Count is above 0 */
+ if (WaitBlock->ShareCount > 0)
+ {
+ /* This shouldn't be an exclusive wait block */
+ ASSERT(WaitBlock->Flags & EX_PUSH_LOCK_FLAGS_EXCLUSIVE);
+
+ /* Do the decrease and check if the lock isn't shared anymore */
+ if (InterlockedDecrement(&WaitBlock->ShareCount) > 0) return;
+ }
+ }
+
+ /*
+ * If nobody was waiting on the block, then we possibly reduced the number
+ * of times the pushlock was shared, and we unlocked it.
+ * If someone was waiting, and more then one person is waiting, then we
+ * reduced the number of times the pushlock is shared in the wait block.
+ * Therefore, at this point, we can now 'satisfy' the wait.
+ */
+ for (;;)
+ {
+ /* Now we need to see if it's waking */
+ if (OldValue.Waking)
+ {
+ /* Remove the lock and multiple shared bits */
+ NewValue.Value = OldValue.Value;
+ NewValue.MultipleShared = FALSE;
+ NewValue.Locked = FALSE;
+
+ /* Sanity check */
+ ASSERT(NewValue.Waking && !NewValue.Locked && !NewValue.MultipleShared);
+
+ /* Write the new value */
+ NewValue.Ptr = InterlockedCompareExchangePointer(PushLock,
+ NewValue.Ptr,
+ OldValue.Ptr);
+ if (NewValue.Value == OldValue.Value) return;
+ }
+ else
+ {
+ /* Remove the lock and multiple shared bits */
+ NewValue.Value = OldValue.Value;
+ NewValue.MultipleShared = FALSE;
+ NewValue.Locked = FALSE;
+
+ /* It's not already waking, so add the wake bit */
+ NewValue.Waking = TRUE;
+
+ /* Sanity check */
+ ASSERT(NewValue.Waking && !NewValue.Locked && !NewValue.MultipleShared);
+
+ /* Write the new value */
+ WakeValue = NewValue;
+ NewValue.Ptr = InterlockedCompareExchangePointer(PushLock,
+ NewValue.Ptr,
+ OldValue.Ptr);
+ if (NewValue.Value != OldValue.Value) continue;
+
+ /* The write was successful. The pushlock is Unlocked and Waking */
+ ExfWakePushLock(PushLock, WakeValue);
+ return;
+ }
+ }
+ }
+ }
+}
+
+/*++
+ * @name ExfReleasePushLockShared
+ * @implemented NT5.2
+ *
+ * The ExfReleasePushLockShared macro releases a previously acquired PushLock.
+ *
+ * @params PushLock
+ * Pointer to a previously acquired pushlock.
+ *
+ * @return None.
+ *
+ * @remarks Callers of ExReleasePushLockShared must be running at IRQL <= APC_LEVEL.
+ * This macro should usually be paired up with KeLeaveCriticalRegion.
+ *
+ *--*/
+VOID
+FASTCALL
+ExfReleasePushLockShared(PEX_PUSH_LOCK PushLock)
+{
+ EX_PUSH_LOCK OldValue = *PushLock, NewValue, WakeValue;
+ PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock, LastWaitBlock;
+
+ /* Check if someone is waiting on the lock */
+ while (!OldValue.Waiting)
+ {
+ /* Check if it's shared */
+ if (OldValue.Shared > 1)
+ {
+ /* Write the Old Value but decrease share count */
+ NewValue = OldValue;
+ NewValue.Shared--;
+ }
+ else
+ {
+ /* Simply clear the lock */
+ NewValue.Value = 0;
+ }
+
+ /* Write the New Value */
+ NewValue.Ptr = InterlockedCompareExchangePointer(PushLock,
+ NewValue.Ptr,
+ OldValue.Ptr);
+ if (NewValue.Value == OldValue.Value) return;
+
+ /* Did it enter a wait state? */
+ OldValue = NewValue;
}
/* Ok, we do know someone is waiting on it. Are there more then one? */
if (OldValue.MultipleShared)
{
- /* Find the last Wait Block */
- for (WaitBlock = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR)OldValue.Ptr &
- ~EX_PUSH_LOCK_PTR_BITS);
- !WaitBlock->Last;
- WaitBlock = WaitBlock->Next);
-
- /* Make sure the Share Count is above 0 */
- if (WaitBlock->ShareCount > 0)
- {
- /* This shouldn't be an exclusive wait block */
- ASSERT(WaitBlock->Flags & EX_PUSH_LOCK_FLAGS_EXCLUSIVE);
-
- /* Do the decrease and check if the lock isn't shared anymore */
- if (InterlockedDecrement(&WaitBlock->ShareCount) > 0) return;
- }
+ /* Get the wait block */
+ WaitBlock = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR)OldValue.Ptr &
+ ~EX_PUSH_LOCK_PTR_BITS);
+
+ /* Loop until we find the last wait block */
+ while (TRUE)
+ {
+ /* Get the last wait block */
+ LastWaitBlock = WaitBlock->Last;
+
+ /* Did it exist? */
+ if (LastWaitBlock)
+ {
+ /* Choose it */
+ WaitBlock = LastWaitBlock;
+ break;
+ }
+
+ /* Keep searching */
+ WaitBlock = WaitBlock->Next;
+ }
+
+ /* Sanity checks */
+ ASSERT(WaitBlock->ShareCount > 0);
+ ASSERT(WaitBlock->Flags & EX_PUSH_LOCK_FLAGS_EXCLUSIVE);
+
+ /* Do the decrease and check if the lock isn't shared anymore */
+ if (InterlockedDecrement(&WaitBlock->ShareCount) > 0) return;
}
/*
@@ -864,131 +1028,14 @@
ASSERT(NewValue.Waking && !NewValue.Locked && !NewValue.MultipleShared);
/* Write the new value */
+ WakeValue = NewValue;
NewValue.Ptr = InterlockedCompareExchangePointer(PushLock,
NewValue.Ptr,
OldValue.Ptr);
if (NewValue.Value != OldValue.Value) continue;
/* The write was successful. The pushlock is Unlocked and Waking */
- ExfWakePushLock(PushLock, NewValue);
- return;
- }
- }
-}
-
-/*++
- * @name ExfReleasePushLockShared
- * @implemented NT5.2
- *
- * The ExfReleasePushLockShared macro releases a previously acquired PushLock.
- *
- * @params PushLock
- * Pointer to a previously acquired pushlock.
- *
- * @return None.
- *
- * @remarks Callers of ExReleasePushLockShared must be running at IRQL <= APC_LEVEL.
- * This macro should usually be paired up with KeLeaveCriticalRegion.
- *
- *--*/
-VOID
-FASTCALL
-ExfReleasePushLockShared(PEX_PUSH_LOCK PushLock)
-{
- EX_PUSH_LOCK OldValue = *PushLock;
- EX_PUSH_LOCK NewValue;
- PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock;
-
- /* Check if someone is waiting on the lock */
- while (!OldValue.Waiting)
- {
- /* Check if it's shared */
- if (OldValue.Shared > 1)
- {
- /* Write the Old Value but decrease share count */
- NewValue = OldValue;
- NewValue.Shared--;
- }
- else
- {
- /* Simply clear the lock */
- NewValue.Value = 0;
- }
-
- /* Write the New Value */
- NewValue.Ptr = InterlockedCompareExchangePointer(PushLock,
- NewValue.Ptr,
- OldValue.Ptr);
- if (NewValue.Value == OldValue.Value) return;
-
- /* Did it enter a wait state? */
- OldValue = NewValue;
- }
-
- /* Ok, we do know someone is waiting on it. Are there more then one? */
- if (OldValue.MultipleShared)
- {
- /* Find the last Wait Block */
- for (WaitBlock = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR)OldValue.Ptr &
- ~EX_PUSH_LOCK_PTR_BITS);
- !WaitBlock->Last;
- WaitBlock = WaitBlock->Next);
-
- /* Sanity checks */
- ASSERT(WaitBlock->ShareCount > 0);
- ASSERT(WaitBlock->Flags & EX_PUSH_LOCK_FLAGS_EXCLUSIVE);
-
- /* Do the decrease and check if the lock isn't shared anymore */
- if (InterlockedDecrement(&WaitBlock->ShareCount) > 0) return;
- }
-
- /*
- * If nobody was waiting on the block, then we possibly reduced the number
- * of times the pushlock was shared, and we unlocked it.
- * If someone was waiting, and more then one person is waiting, then we
- * reduced the number of times the pushlock is shared in the wait block.
- * Therefore, at this point, we can now 'satisfy' the wait.
- */
- for (;;)
- {
- /* Now we need to see if it's waking */
- if (OldValue.Waking)
- {
- /* Remove the lock and multiple shared bits */
- NewValue.Value = OldValue.Value;
- NewValue.MultipleShared = FALSE;
- NewValue.Locked = FALSE;
-
- /* Sanity check */
- ASSERT(NewValue.Waking && !NewValue.Locked && !NewValue.MultipleShared);
-
- /* Write the new value */
- NewValue.Ptr = InterlockedCompareExchangePointer(PushLock,
- NewValue.Ptr,
- OldValue.Ptr);
- if (NewValue.Value == OldValue.Value) return;
- }
- else
- {
- /* Remove the lock and multiple shared bits */
- NewValue.Value = OldValue.Value;
- NewValue.MultipleShared = FALSE;
- NewValue.Locked = FALSE;
-
- /* It's not already waking, so add the wake bit */
- NewValue.Waking = TRUE;
-
- /* Sanity check */
- ASSERT(NewValue.Waking && !NewValue.Locked && !NewValue.MultipleShared);
-
- /* Write the new value */
- NewValue.Ptr = InterlockedCompareExchangePointer(PushLock,
- NewValue.Ptr,
- OldValue.Ptr);
- if (NewValue.Value != OldValue.Value) continue;
-
- /* The write was successful. The pushlock is Unlocked and Waking */
- ExfWakePushLock(PushLock, NewValue);
+ ExfWakePushLock(PushLock, WakeValue);
return;
}
}
@@ -1094,21 +1141,19 @@
* If the Pushlock is not waiting on anything, or if it's already waking up
* and locked, don't do anything
*/
- if (!(OldValue.Value == (EX_PUSH_LOCK_WAKING | EX_PUSH_LOCK_LOCK)) &&
- (OldValue.Waiting))
- {
- /* Make it Waking */
- NewValue = OldValue;
- NewValue.Waking = TRUE;
-
- /* Write the New Value */
- if (InterlockedCompareExchangePointer(PushLock,
- NewValue.Ptr,
- OldValue.Ptr) == OldValue.Ptr)
- {
- /* Wake the Pushlock */
- ExfWakePushLock(PushLock, NewValue);
- }
+ if ((OldValue.Waking) || (OldValue.Locked) || !(OldValue.Waiting)) return;
+
+ /* Make it Waking */
+ NewValue = OldValue;
+ NewValue.Waking = TRUE;
+
+ /* Write the New Value */
+ if (InterlockedCompareExchangePointer(PushLock,
+ NewValue.Ptr,
+ OldValue.Ptr) == OldValue.Ptr)
+ {
+ /* Wake the Pushlock */
+ ExfWakePushLock(PushLock, NewValue);
}
}
@@ -1142,20 +1187,20 @@
if (WaitBlock->Next) KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
/* Start block loop */
- for (;;)
+ while (WaitBlock)
{
/* Get the next block */
NextWaitBlock = WaitBlock->Next;
/* Remove the wait flag from the Wait block */
- if (InterlockedBitTestAndReset(&WaitBlock->Flags, 1))
+ if (!InterlockedBitTestAndReset(&WaitBlock->Flags, EX_PUSH_LOCK_FLAGS_WAIT_V))
{
/* Nobody removed the flag before us, so signal the event */
KeSetEventBoostPriority(&WaitBlock->WakeEvent, NULL);
}
- /* Check if there was a next block */
- if (!NextWaitBlock) break;
+ /* Try the next one */
+ WaitBlock = NextWaitBlock;
}
/* Lower IRQL if needed */
Propchange: trunk/reactos/ntoskrnl/ex/pushlock.c
------------------------------------------------------------------------------
--- svn:needs-lock (original)
+++ svn:needs-lock (removed)
@@ -1,1 +1,0 @@
-*
Modified: trunk/reactos/ntoskrnl/include/internal/ex.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ex.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/ex.h [iso-8859-1] Tue Apr 1 13:14:01 2008
@@ -26,6 +26,7 @@
extern ULONG NtGlobalFlag;
extern ULONG ExpInitializationPhase;
extern ULONG ExpAltTimeZoneBias;
+extern LIST_ENTRY ExSystemLookasideListHead;
typedef struct _EXHANDLE
{
@@ -711,7 +712,6 @@
if (InterlockedBitTestAndSet((PLONG)PushLock, EX_PUSH_LOCK_LOCK_V))
{
/* Someone changed it, use the slow path */
- // DbgPrint("%s - Contention!\n", __FUNCTION__);
ExfAcquirePushLockExclusive(PushLock);
}
@@ -750,6 +750,7 @@
}
/* Got acquired */
+ ASSERT (PushLock->Locked);
return TRUE;
}
@@ -783,7 +784,6 @@
if (ExpChangePushlock(PushLock, NewValue.Ptr, 0))
{
/* Someone changed it, use the slow path */
- // DbgPrint("%s - Contention!\n", __FUNCTION__);
ExfAcquirePushLockShared(PushLock);
}
@@ -897,7 +897,6 @@
if (ExpChangePushlock(PushLock, 0, OldValue.Ptr) != OldValue.Ptr)
{
/* There are still other people waiting on it */
- DbgPrint("%s - Contention!\n", __FUNCTION__);
ExfReleasePushLockShared(PushLock);
}
}
@@ -945,7 +944,6 @@
if ((OldValue.Waiting) && !(OldValue.Waking))
{
/* Wake it up */
- DbgPrint("%s - Contention!\n", __FUNCTION__);
ExfTryToWakePushLock(PushLock);
}
}
@@ -997,7 +995,6 @@
OldValue.Ptr))
{
/* We have waiters, use the long path */
- // DbgPrint("%s - Contention!\n", __FUNCTION__);
ExfReleasePushLock(PushLock);
}
}