[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