summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/vxlib.c10
-rw-r--r--gcc/gthr-vxworks.h23
3 files changed, 35 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d7270194d26..056f732dd58 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/config/vxlib.c b/gcc/config/vxlib.c
index 686d66de01f..0ff996cfced 100644
--- a/gcc/config/vxlib.c
+++ b/gcc/config/vxlib.c
@@ -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
diff --git a/gcc/gthr-vxworks.h b/gcc/gthr-vxworks.h
index c2fb8e6729f..dee15731f0a 100644
--- a/gcc/gthr-vxworks.h
+++ b/gcc/gthr-vxworks.h
@@ -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));