Author: dgorbachev Date: Fri Feb 6 08:47:19 2009 New Revision: 39441
URL: http://svn.reactos.org/svn/reactos?rev=39441&view=rev Log: - Fix spinning on locks on SMP. - Alignment bug in GCC 4.3.3.
Modified: trunk/reactos/lib/rtl/srw.c trunk/reactos/ntoskrnl/ex/pushlock.c trunk/reactos/ntoskrnl/include/internal/ex.h trunk/reactos/ntoskrnl/include/internal/ke.h
Modified: trunk/reactos/lib/rtl/srw.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/srw.c?rev=39441&... ============================================================================== --- trunk/reactos/lib/rtl/srw.c [iso-8859-1] (original) +++ trunk/reactos/lib/rtl/srw.c [iso-8859-1] Fri Feb 6 08:47:19 2009 @@ -44,7 +44,8 @@ RTL_SRWLOCK_SHARED | RTL_SRWLOCK_CONTENTION_LOCK) #define RTL_SRWLOCK_BITS 4
-#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40300) && !defined(_M_AMD64) +#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40300) || \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ == 40303) /* This macro will cause the code to assert if compiled with a buggy version of GCC that doesn't align the wait blocks properly on the stack! */ #define ASSERT_SRW_WAITBLOCK(ptr) \
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] Fri Feb 6 08:47:19 2009 @@ -14,7 +14,8 @@
/* DATA **********************************************************************/
-ULONG ExPushLockSpinCount; +ULONG ExPushLockSpinCount = 0; + #undef EX_PUSH_LOCK #undef PEX_PUSH_LOCK
@@ -36,8 +37,11 @@ NTAPI ExpInitializePushLocks(VOID) { +#ifdef CONFIG_SMP /* Initialize an internal 1024-iteration spin for MP CPUs */ - ExPushLockSpinCount = (KeNumberProcessors == 1) ? 0 : 1024; + if (KeNumberProcessors > 1) + ExPushLockSpinCount = 1024; +#endif }
/*++ @@ -309,7 +313,6 @@ IN PVOID WaitBlock, IN PLARGE_INTEGER Timeout) { - ULONG i; NTSTATUS Status;
/* Initialize the wait event */ @@ -317,23 +320,22 @@ SynchronizationEvent, FALSE);
+#ifdef CONFIG_SMP /* Spin on the push lock if necessary */ - i = ExPushLockSpinCount; - if (i) - { - /* Spin */ - while (--i) + if (ExPushLockSpinCount) + { + ULONG i = ExPushLockSpinCount; + + do { /* Check if we got lucky and can leave early */ - if (!(((PEX_PUSH_LOCK_WAIT_BLOCK)WaitBlock)->Flags & - EX_PUSH_LOCK_WAITING)) - { - /* This wait block isn't waiting anymore, we can leave */ + if (!(*(volatile LONG *)&((PEX_PUSH_LOCK_WAIT_BLOCK)WaitBlock)->Flags & EX_PUSH_LOCK_WAITING)) return STATUS_SUCCESS; - } + YieldProcessor(); - } - } + } while (--i); + } +#endif
/* Now try to remove the wait bit */ if (InterlockedBitTestAndReset(&((PEX_PUSH_LOCK_WAIT_BLOCK)WaitBlock)->Flags, @@ -463,7 +465,6 @@ { EX_PUSH_LOCK OldValue = *PushLock, NewValue, TempValue; BOOLEAN NeedWake; - ULONG i; DEFINE_WAIT_BLOCK(WaitBlock);
/* Start main loop */ @@ -583,13 +584,21 @@ /* Set up the Wait Gate */ KeInitializeGate(&WaitBlock->WakeGate);
+#ifdef CONFIG_SMP /* Now spin on the push lock if necessary */ - i = ExPushLockSpinCount; - if ((i) && (WaitBlock->Flags & EX_PUSH_LOCK_WAITING)) - { - /* Spin */ - while (--i) YieldProcessor(); - } + if (ExPushLockSpinCount) + { + ULONG i = ExPushLockSpinCount; + + do + { + if (!(*(volatile LONG *)&WaitBlock->Flags & EX_PUSH_LOCK_WAITING)) + break; + + YieldProcessor(); + } while (--i); + } +#endif
/* Now try to remove the wait bit */ if (InterlockedBitTestAndReset(&WaitBlock->Flags, 1)) @@ -629,7 +638,6 @@ { EX_PUSH_LOCK OldValue = *PushLock, NewValue; BOOLEAN NeedWake; - ULONG i; DEFINE_WAIT_BLOCK(WaitBlock);
/* Start main loop */ @@ -742,13 +750,21 @@ /* Set up the Wait Gate */ KeInitializeGate(&WaitBlock->WakeGate);
+#ifdef CONFIG_SMP /* Now spin on the push lock if necessary */ - i = ExPushLockSpinCount; - if ((i) && (WaitBlock->Flags & EX_PUSH_LOCK_WAITING)) - { - /* Spin */ - while (--i) YieldProcessor(); - } + if (ExPushLockSpinCount) + { + ULONG i = ExPushLockSpinCount; + + do + { + if (!(*(volatile LONG *)&WaitBlock->Flags & EX_PUSH_LOCK_WAITING)) + break; + + YieldProcessor(); + } while (--i); + } +#endif
/* Now try to remove the wait bit */ if (InterlockedBitTestAndReset(&WaitBlock->Flags, 1))
Modified: trunk/reactos/ntoskrnl/include/internal/ex.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/e... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ex.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/ex.h [iso-8859-1] Fri Feb 6 08:47:19 2009 @@ -94,7 +94,8 @@ // // Detect old GCC // -#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40300) +#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40300) || \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ == 40303)
#define DEFINE_WAIT_BLOCK(x) \ struct _AlignHack \
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/k... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] Fri Feb 6 08:47:19 2009 @@ -168,8 +168,8 @@ { \ (Header)->Type = t; \ (Header)->Absolute = 0; \ + (Header)->Size = s; \ (Header)->Inserted = 0; \ - (Header)->Size = s; \ (Header)->SignalState = State; \ InitializeListHead(&((Header)->WaitListHead)); \ }