[ros-diffs] [dgorbachev] 39441: - Fix spinning on locks on SMP. - Alignment bug in GCC 4.3.3.

dgorbachev at svn.reactos.org dgorbachev at svn.reactos.org
Fri Feb 6 15:47:21 CET 2009


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&r1=39440&r2=39441&view=diff
==============================================================================
--- 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=39441&r1=39440&r2=39441&view=diff
==============================================================================
--- 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/ex.h?rev=39441&r1=39440&r2=39441&view=diff
==============================================================================
--- 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/ke.h?rev=39441&r1=39440&r2=39441&view=diff
==============================================================================
--- 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));                          \
 }



More information about the Ros-diffs mailing list