Build mono runtime under none desktop Windows API family, adjustments and cleanup.
[mono.git] / mono / utils / atomic.c
old mode 100755 (executable)
new mode 100644 (file)
index 362bb8d..543e8ce
@@ -12,7 +12,7 @@
 #include <glib.h>
 
 #include <mono/utils/atomic.h>
-#include <mono/utils/mono-mutex.h>
+#include <mono/utils/mono-compiler.h>
 
 #if defined (WAPI_NO_ATOMIC_ASM) || defined (BROKEN_64BIT_ATOMICS_INTRINSIC)
 
 
 static pthread_mutex_t spin G_GNUC_UNUSED = PTHREAD_MUTEX_INITIALIZER;
 
-static mono_once_t spin_once G_GNUC_UNUSED = MONO_ONCE_INIT;
-
-static void spin_init(void)
-{
-       g_warning("Using non-atomic functions!  Expect race conditions when using process-shared handles!");
-}
-
 #define NEED_64BIT_CMPXCHG_FALLBACK
 
 #endif
@@ -39,8 +32,6 @@ gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch,
        gint32 old;
        int ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        ret = pthread_mutex_lock(&spin);
@@ -65,8 +56,6 @@ gpointer InterlockedCompareExchangePointer(volatile gpointer *dest,
        gpointer old;
        int ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        ret = pthread_mutex_lock(&spin);
@@ -90,8 +79,6 @@ gint32 InterlockedAdd(volatile gint32 *dest, gint32 add)
        gint32 ret;
        int thr_ret;
 
-       mono_once(&spin_once, spin_init);
-
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -113,8 +100,6 @@ gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add)
        gint64 ret;
        int thr_ret;
 
-       mono_once(&spin_once, spin_init);
-
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -136,8 +121,6 @@ gint32 InterlockedIncrement(volatile gint32 *dest)
        gint32 ret;
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -159,8 +142,6 @@ gint64 InterlockedIncrement64(volatile gint64 *dest)
        gint64 ret;
        int thr_ret;
 
-       mono_once(&spin_once, spin_init);
-
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -182,8 +163,6 @@ gint32 InterlockedDecrement(volatile gint32 *dest)
        gint32 ret;
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -205,8 +184,6 @@ gint64 InterlockedDecrement64(volatile gint64 *dest)
        gint64 ret;
        int thr_ret;
 
-       mono_once(&spin_once, spin_init);
-
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -228,8 +205,6 @@ gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
        gint32 ret;
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -251,8 +226,6 @@ gint64 InterlockedExchange64(volatile gint64 *dest, gint64 exch)
        gint64 ret;
        int thr_ret;
 
-       mono_once(&spin_once, spin_init);
-
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -274,8 +247,6 @@ gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch)
        gpointer ret;
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -297,8 +268,6 @@ gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
        gint32 ret;
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -320,8 +289,6 @@ gint64 InterlockedExchangeAdd64(volatile gint64 *dest, gint64 add)
        gint64 ret;
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -343,8 +310,6 @@ gint8 InterlockedRead8(volatile gint8 *src)
        gint8 ret;
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -365,8 +330,6 @@ gint16 InterlockedRead16(volatile gint16 *src)
        gint16 ret;
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -387,8 +350,6 @@ gint32 InterlockedRead(volatile gint32 *src)
        gint32 ret;
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -409,8 +370,6 @@ gint64 InterlockedRead64(volatile gint64 *src)
        gint64 ret;
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -431,8 +390,6 @@ gpointer InterlockedReadPointer(volatile gpointer *src)
        gpointer ret;
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -452,8 +409,6 @@ void InterlockedWrite(volatile gint8 *dst, gint8 val)
 {
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -471,8 +426,6 @@ void InterlockedWrite16(volatile gint16 *dst, gint16 val)
 {
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -490,8 +443,6 @@ void InterlockedWrite(volatile gint32 *dst, gint32 val)
 {
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -509,8 +460,6 @@ void InterlockedWrite64(volatile gint64 *dst, gint64 val)
 {
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -528,8 +477,6 @@ void InterlockedWritePointer(volatile gpointer *dst, gpointer val)
 {
        int thr_ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        thr_ret = pthread_mutex_lock(&spin);
@@ -557,10 +504,56 @@ InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
        return __sync_val_compare_and_swap (dest, comp, exch);
 }
 
-#elif defined (HAVE_64BIT_CMPXCHG_FALLBACK)
+#elif defined (__arm__) && defined (HAVE_ARMV7) && (defined(TARGET_IOS) || defined(TARGET_WATCHOS) || defined(TARGET_ANDROID))
+
+#if defined (TARGET_IOS) || defined (TARGET_WATCHOS)
+
+#ifndef __clang__
+#error "Not supported."
+#endif
+
+gint64
+InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
+{
+       return  __sync_val_compare_and_swap (dest, comp, exch);
+}
+
+#elif defined (TARGET_ANDROID)
+
+/* Some Android systems can't find the 64-bit CAS intrinsic at runtime,
+ * so we have to roll our own...
+ */
+
+gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp) __attribute__ ((naked));
+
+gint64
+InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
+{
+       __asm__ (
+               "push           {r4, r5, r6, r7}\n"
+               "ldrd           r4, [sp, #16]\n"
+               "dmb            sy\n"
+       "1:\n"
+               "ldrexd         r6, [r0]\n"
+               "cmp            r7, r5\n"
+               "cmpeq          r6, r4\n"
+               "bne            2f\n"
+               "strexd         r1, r2, [r0]\n"
+               "cmp            r1, #0\n"
+               "bne            1b\n"
+       "2:\n"
+               "dmb            sy\n"
+               "mov            r0, r6\n"
+               "mov            r1, r7\n"
+               "pop            {r4, r5, r6, r7}\n"
+               "bx                     lr\n"
+       );
+}
+
+#else
+
+#error "Need a 64-bit CAS fallback!"
 
-#ifdef ENABLE_EXTENSION_MODULE
-#include "../../../mono-extensions/mono/utils/atomic.c"
 #endif
 
 #else
@@ -571,8 +564,6 @@ InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
        gint64 old;
        int ret;
        
-       mono_once(&spin_once, spin_init);
-       
        pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
                              (void *)&spin);
        ret = pthread_mutex_lock(&spin);
@@ -591,6 +582,9 @@ InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
        return(old);
 }
 
+#endif
 #endif
 
+#if !defined (WAPI_NO_ATOMIC_ASM) && !defined (BROKEN_64BIT_ATOMICS_INTRINSIC) && !defined (NEED_64BIT_CMPXCHG_FALLBACK)
+MONO_EMPTY_SOURCE_FILE (atomic);
 #endif