#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
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
{
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);
{
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);
{
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);
{
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);
{
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);
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
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);
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