From 24a40b356f07a2a4d50d4c36e5bbb86ef06d3925 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 22 Apr 2009 10:53:53 +0000 Subject: [PATCH] gthr-vxworks.h (struct __gthread_once_t): Add alignment and padding for PPC. * 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 | 7 +++++++ gcc/config/vxlib.c | 10 +++++++++- gcc/gthr-vxworks.h | 23 +++++++++++++++++++---- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d7270194d26b..056f732dd586 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2009-04-22 Nathan Sidwell + + * 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 * config/sh/sh.c (shift_insns_rtx, shiftcosts, gen_shifty_op, diff --git a/gcc/config/vxlib.c b/gcc/config/vxlib.c index 686d66de01f9..0ff996cfced8 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 c2fb8e6729f0..dee15731f0ac 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));