[Mono-dev] [PATCH] use gcc 4.1 atomic built-ins
Andreas Färber
andreas.faerber at web.de
Thu Aug 7 12:39:13 EDT 2008
Hello,
Am 07.08.2008 um 16:23 schrieb Olaf Hering:
> While trying to get mono running on powerpc64, I experienced a hang in
> GC_lock on my POWER6 test system. This was caused by incorrect
> powerpc64
> locking code in libgc.
Usually, random changes to libgc are not allowed. You can either
download and use an up-to-date Boehm GC (e.g., 7.1) or disable the GC
completely while porting (--with-gc=none).
If it's not in the latest Boehm GC it would be a good idea to submit
it upstream.
Andreas
> With this change, the binary got a bit further. But it still fails for
> other unrelated reasons.
>
> gcc 4.1 has helper functions for atomic operations:
> http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
>
>
> Please review.
>
> --- a/libgc/include/private/gc_locks.h
> +++ b/libgc/include/private/gc_locks.h
> @@ -88,6 +88,18 @@
> /* acquisition and release. We need this for correct operation of
> the */
> /* incremental GC. */
> # ifdef __GNUC__
> +#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 1
> +static inline int GC_test_and_set(volatile unsigned int *addr)
> +{
> +#define GC_TEST_AND_SET_DEFINED
> + return (int)__sync_lock_test_and_set(addr, 1);
> +}
> +static inline void GC_clear(volatile unsigned int *addr)
> +{
> +#define GC_CLEAR_DEFINED
> + __sync_lock_test_and_set(addr, 0);
> +}
> +#else /* ! __GNUC__ 4.1+ */
> # if defined(I386)
> inline static int GC_test_and_set(volatile unsigned int
> *addr) {
> int oldval;
> @@ -288,6 +300,7 @@
> return ret;
> }
> # endif
> +# endif /* !__GNUC__ 4.1+ */
> # endif /* __GNUC__ */
> # if (defined(ALPHA) && !defined(__GNUC__))
> # ifndef OSF1
> --- a/mono/io-layer/atomic.h
> +++ b/mono/io-layer/atomic.h
> @@ -14,6 +14,39 @@
>
> #include "mono/io-layer/wapi.h"
>
> +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1
> +/* requires gcc 4.1 for atomic built-ins */
> +#define WAPI_ATOMIC_ASM
> +static inline gint32 InterlockedCompareExchange(volatile gint32
> *dest, gint32 exch, gint32 comp)
> +{
> + return __sync_val_compare_and_swap(dest, exch, comp);
> +}
> +static inline gpointer InterlockedCompareExchangePointer(volatile
> gpointer *dest, gpointer exch, gpointer comp)
> +{
> + return __sync_val_compare_and_swap(dest, exch, comp);
> +}
> +static inline gint32 InterlockedIncrement(volatile gint32 *dest)
> +{
> + return __sync_fetch_and_add(dest, 1) + 1;
> +}
> +static inline gint32 InterlockedDecrement(volatile gint32 *dest)
> +{
> + return __sync_fetch_and_sub(dest, 1) - 1;
> +}
> +static inline gint32 InterlockedExchange(volatile gint32 *dest,
> gint32 exch)
> +{
> + return __sync_lock_test_and_set(dest, exch);
> +}
> +static inline gpointer InterlockedExchangePointer(volatile gpointer
> *dest, gpointer exch)
> +{
> + return __sync_lock_test_and_set(dest, exch);
> +}
> +static inline gint32 InterlockedExchangeAdd(volatile gint32 *dest,
> gint32 add)
> +{
> + return __sync_fetch_and_add(dest, add);
> +}
> +#else /* !__GNUC__ 4.1+ */
> +
> #if defined(__i386__) || defined(__x86_64__)
> #define WAPI_ATOMIC_ASM
>
> @@ -1025,4 +1058,6 @@ extern gint32 InterlockedExchangeAdd(vol
>
> #endif
>
> +#endif /* !__GNUC__ 4.1+ */
> +
> #endif /* _WAPI_ATOMIC_H_ */
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
More information about the Mono-devel-list
mailing list