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/utils/atomic.h>
17 #ifdef WAPI_NO_ATOMIC_ASM
19 static pthread_mutex_t spin = PTHREAD_MUTEX_INITIALIZER;
20 static mono_once_t spin_once=MONO_ONCE_INIT;
22 static void spin_init(void)
24 g_warning("Using non-atomic functions! Expect race conditions when using process-shared handles!");
27 gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch,
33 mono_once(&spin_once, spin_init);
35 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
37 ret = pthread_mutex_lock(&spin);
45 ret = pthread_mutex_unlock(&spin);
48 pthread_cleanup_pop (0);
53 gpointer InterlockedCompareExchangePointer(volatile gpointer *dest,
54 gpointer exch, gpointer comp)
59 mono_once(&spin_once, spin_init);
61 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
63 ret = pthread_mutex_lock(&spin);
71 ret = pthread_mutex_unlock(&spin);
74 pthread_cleanup_pop (0);
79 gint32 InterlockedIncrement(volatile gint32 *dest)
84 mono_once(&spin_once, spin_init);
86 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
88 thr_ret = pthread_mutex_lock(&spin);
89 g_assert (thr_ret == 0);
94 thr_ret = pthread_mutex_unlock(&spin);
95 g_assert (thr_ret == 0);
97 pthread_cleanup_pop (0);
102 gint32 InterlockedDecrement(volatile gint32 *dest)
107 mono_once(&spin_once, spin_init);
109 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
111 thr_ret = pthread_mutex_lock(&spin);
112 g_assert (thr_ret == 0);
117 thr_ret = pthread_mutex_unlock(&spin);
118 g_assert (thr_ret == 0);
120 pthread_cleanup_pop (0);
125 gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
130 mono_once(&spin_once, spin_init);
132 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
134 thr_ret = pthread_mutex_lock(&spin);
135 g_assert (thr_ret == 0);
140 thr_ret = pthread_mutex_unlock(&spin);
141 g_assert (thr_ret == 0);
143 pthread_cleanup_pop (0);
148 gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch)
153 mono_once(&spin_once, spin_init);
155 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
157 thr_ret = pthread_mutex_lock(&spin);
158 g_assert (thr_ret == 0);
163 thr_ret = pthread_mutex_unlock(&spin);
164 g_assert (thr_ret == 0);
166 pthread_cleanup_pop (0);
171 gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
176 mono_once(&spin_once, spin_init);
178 pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
180 thr_ret = pthread_mutex_lock(&spin);
181 g_assert (thr_ret == 0);
186 thr_ret = pthread_mutex_unlock(&spin);
187 g_assert (thr_ret == 0);
189 pthread_cleanup_pop (0);