2 * atomic.c: Workarounds for atomic operations for platforms that dont have
3 * really atomic asm functions in atomic.h
6 * Dick Porter (dick@ximian.com)
8 * (C) 2002 Ximian, Inc.
15 #include "mono/io-layer/wapi.h"
17 #ifdef WAPI_ATOMIC_ASM
18 #if defined(sparc) || defined (__sparc__)
19 volatile unsigned char _wapi_sparc_lock;
23 static pthread_mutex_t spin = PTHREAD_MUTEX_INITIALIZER;
24 static mono_once_t spin_once=MONO_ONCE_INIT;
26 static void spin_init(void)
28 g_warning("Using non-atomic functions!");
31 gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch,
37 mono_once(&spin_once, spin_init);
39 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
41 ret = pthread_mutex_lock(&spin);
49 ret = pthread_mutex_unlock(&spin);
52 pthread_cleanup_pop (0);
57 gpointer InterlockedCompareExchangePointer(volatile gpointer *dest,
58 gpointer exch, gpointer comp)
63 mono_once(&spin_once, spin_init);
65 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
67 ret = pthread_mutex_lock(&spin);
75 ret = pthread_mutex_unlock(&spin);
78 pthread_cleanup_pop (0);
83 gint32 InterlockedIncrement(volatile gint32 *dest)
88 mono_once(&spin_once, spin_init);
90 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
92 thr_ret = pthread_mutex_lock(&spin);
93 g_assert (thr_ret == 0);
98 thr_ret = pthread_mutex_unlock(&spin);
99 g_assert (thr_ret == 0);
101 pthread_cleanup_pop (0);
106 gint32 InterlockedDecrement(volatile gint32 *dest)
111 mono_once(&spin_once, spin_init);
113 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
115 thr_ret = pthread_mutex_lock(&spin);
116 g_assert (thr_ret == 0);
121 thr_ret = pthread_mutex_unlock(&spin);
122 g_assert (thr_ret == 0);
124 pthread_cleanup_pop (0);
129 gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
134 mono_once(&spin_once, spin_init);
136 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
138 thr_ret = pthread_mutex_lock(&spin);
139 g_assert (thr_ret == 0);
144 thr_ret = pthread_mutex_unlock(&spin);
145 g_assert (thr_ret == 0);
147 pthread_cleanup_pop (0);
152 gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch)
157 mono_once(&spin_once, spin_init);
159 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
161 thr_ret = pthread_mutex_lock(&spin);
162 g_assert (thr_ret == 0);
167 thr_ret = pthread_mutex_unlock(&spin);
168 g_assert (thr_ret == 0);
170 pthread_cleanup_pop (0);
175 gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
180 mono_once(&spin_once, spin_init);
182 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
184 thr_ret = pthread_mutex_lock(&spin);
185 g_assert (thr_ret == 0);
190 thr_ret = pthread_mutex_unlock(&spin);
191 g_assert (thr_ret == 0);
193 pthread_cleanup_pop (0);