[Mono-dev] [PATCH] use gcc 4.1 atomic built-ins

Olaf Hering olh at suse.de
Thu Aug 7 10:23:58 EDT 2008


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.
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_ */


More information about the Mono-devel-list mailing list