[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