gthr-vxworks.h (struct __gthread_once_t): Add alignment and padding for PPC.
authorNathan Sidwell <nathan@codesourcery.com>
Wed, 22 Apr 2009 10:53:53 +0000 (10:53 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 22 Apr 2009 10:53:53 +0000 (10:53 +0000)
* gthr-vxworks.h (struct __gthread_once_t): Add alignment and
padding for PPC.
(__GTHREAD_ONCE_INIT): Adjust ppc initializer.
* config/vxlib.c (__gthread_once): Add race guard for PPC.

From-SVN: r146566

gcc/ChangeLog
gcc/config/vxlib.c
gcc/gthr-vxworks.h

index d7270194d26b4501ac6bc776755586c3fda505d7..056f732dd5867b6f49143b861db9a2bfaa08a554 100644 (file)
@@ -1,3 +1,10 @@
+2009-04-22  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * gthr-vxworks.h (struct __gthread_once_t): Add alignment and
+       padding for PPC.
+       (__GTHREAD_ONCE_INIT): Adjust ppc initializer.
+       * config/vxlib.c (__gthread_once): Add race guard for PPC.
+
 2009-04-22  Paolo Bonzini  <bonzini@gnu.org>
 
        * config/sh/sh.c (shift_insns_rtx, shiftcosts, gen_shifty_op,
index 686d66de01f9b831265abb79e79bc09ef6c3f399..0ff996cfced8a3d73bda280d7d99279288c7498e 100644 (file)
@@ -65,7 +65,15 @@ __gthread_once (__gthread_once_t *guard, void (*func)(void))
   __gthread_lock_library ();
 #else
   while (!vxTas ((void *)&guard->busy))
-    taskDelay (1);
+    {
+#ifdef __PPC__
+      /* This can happen on powerpc, which is using all 32 bits
+        of the gthread_once_t structure.  */
+      if (guard->done)
+       return;
+#endif
+      taskDelay (1);
+    }
 #endif
 
   /* Only one thread at a time gets here.  Check ->done again, then
index c2fb8e6729f019a4928f4cd4ce7bf7b2890a3db4..dee15731f0ac0a951712b8a2fcc9099b1c54e716 100644 (file)
@@ -115,17 +115,32 @@ __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
 
 typedef struct
 {
-#ifndef __RTP__
+#if !defined(__RTP__)
+#if defined(__PPC__)
+  __attribute ((aligned (__alignof (unsigned))))
+#endif
   volatile unsigned char busy;
 #endif
   volatile unsigned char done;
+#if !defined(__RTP__) && defined(__PPC__)
+  /* PPC's test-and-set implementation requires a 4 byte aligned
+     object, of which it only sets the first byte.  We use padding
+     here, in order to maintain some amount of backwards
+     compatibility.  Without this padding, gthread_once objects worked
+     by accident because they happen to be static objects and the ppc
+     port automatically increased their alignment to 4 bytes.  */
+  unsigned char pad1;
+  unsigned char pad2;
+#endif
 }
 __gthread_once_t;
 
-#ifndef __RTP__
-# define __GTHREAD_ONCE_INIT { 0, 0 }
-#else
+#if defined (__RTP__)
 # define __GTHREAD_ONCE_INIT { 0 }
+#elif defined (__PPC__) 
+# define __GTHREAD_ONCE_INIT { 0, 0, 0, 0 }
+#else
+# define __GTHREAD_ONCE_INIT { 0, 0 }
 #endif
 
 extern int __gthread_once (__gthread_once_t *__once, void (*__func)(void));