1 #ifndef _WAPI_ATOMIC_H_
2 #define _WAPI_ATOMIC_H_
6 #include "mono/io-layer/wapi.h"
9 #define WAPI_ATOMIC_ASM
12 * NB: The *Pointer() functions here assume that
13 * sizeof(pointer)==sizeof(gint32)
15 * NB2: These asm functions assume 486+ (some of the opcodes dont
16 * exist on 386). If this becomes an issue, we can get configure to
17 * fall back to the non-atomic C versions of these calls.
20 static inline gint32 InterlockedCompareExchange(volatile gint32 *dest,
21 gint32 exch, gint32 comp)
25 __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
26 : "=m" (*dest), "=a" (old)
27 : "r" (exch), "0" (*dest), "a" (comp));
31 static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp)
35 __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
36 : "=m" (*dest), "=a" (old)
37 : "r" (exch), "0" (*dest), "a" (comp));
41 static inline gint32 InterlockedIncrement(volatile gint32 *val)
45 __asm__ __volatile__ ("lock; xaddl %0, %1"
46 : "=r" (tmp), "=m" (*val)
47 : "0" (1), "1" (*val));
52 static inline gint32 InterlockedDecrement(volatile gint32 *val)
56 __asm__ __volatile__ ("lock; xaddl %0, %1"
57 : "=r" (tmp), "=m" (*val)
58 : "0" (-1), "1" (*val));
65 * http://msdn.microsoft.com/library/en-us/dnmag00/html/win320700.asp?frame=true
66 * for the reasons for using cmpxchg and a loop here.
68 static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new)
72 __asm__ __volatile__ ("1:; lock; cmpxchgl %2, %0; jne 1b"
73 : "=m" (*val), "=a" (ret)
74 : "r" (new), "0" (*val), "a" (*val));
79 static inline gpointer InterlockedExchangePointer(volatile gpointer *val,
84 __asm__ __volatile__ ("1:; lock; cmpxchgl %2, %0; jne 1b"
85 : "=m" (*val), "=a" (ret)
86 : "r" (new), "0" (*val), "a" (*val));
91 static inline gint32 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
95 __asm__ __volatile__ ("lock; xaddl %0, %1"
96 : "=r" (ret), "=m" (*val)
97 : "0" (add), "1" (*val));
102 extern gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch, gint32 comp);
103 extern gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp);
104 extern gint32 InterlockedIncrement(volatile gint32 *dest);
105 extern gint32 InterlockedDecrement(volatile gint32 *dest);
106 extern gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch);
107 extern gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch);
108 extern gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add);
111 #endif /* _WAPI_ATOMIC_H_ */