2 * atomic.h: Atomic operations
5 * Dick Porter (dick@ximian.com)
7 * (C) 2002 Ximian, Inc.
10 #ifndef _WAPI_ATOMIC_H_
11 #define _WAPI_ATOMIC_H_
13 #if defined(__NetBSD__)
14 #include <sys/param.h>
16 #if __NetBSD_Version__ > 499004000
17 #include <sys/atomic.h>
18 #define HAVE_ATOMIC_OPS
25 #include "mono/io-layer/wapi.h"
27 #if defined(__NetBSD__) && defined(HAVE_ATOMIC_OPS)
29 #define WAPI_ATOMIC_ASM
30 static inline gint32 InterlockedCompareExchange(volatile gint32 *dest,
31 gint32 exch, gint32 comp)
33 return atomic_cas_32((uint32_t*)dest, comp, exch);
36 static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp)
38 return atomic_cas_ptr(dest, comp, exch);
41 static inline gint32 InterlockedIncrement(volatile gint32 *val)
43 return atomic_inc_32_nv((uint32_t*)val);
46 static inline gint32 InterlockedDecrement(volatile gint32 *val)
48 return atomic_dec_32_nv((uint32_t*)val);
51 static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val)
53 return atomic_swap_32((uint32_t*)val, new_val);
56 static inline gpointer InterlockedExchangePointer(volatile gpointer *val,
59 return atomic_swap_ptr(val, new_val);
62 static inline gint32 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
64 return atomic_add_32_nv((uint32_t*)val, add) - add;
67 #elif defined(__i386__) || defined(__x86_64__)
68 #define WAPI_ATOMIC_ASM
71 * NB: The *Pointer() functions here assume that
72 * sizeof(pointer)==sizeof(gint32)
74 * NB2: These asm functions assume 486+ (some of the opcodes dont
75 * exist on 386). If this becomes an issue, we can get configure to
76 * fall back to the non-atomic C versions of these calls.
79 static inline gint32 InterlockedCompareExchange(volatile gint32 *dest,
80 gint32 exch, gint32 comp)
84 __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
85 : "=m" (*dest), "=a" (old)
86 : "r" (exch), "m" (*dest), "a" (comp));
90 static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp)
94 __asm__ __volatile__ ("lock; "
101 : "=m" (*dest), "=a" (old)
102 : "r" (exch), "m" (*dest), "a" (comp));
107 static inline gint32 InterlockedIncrement(volatile gint32 *val)
111 __asm__ __volatile__ ("lock; xaddl %0, %1"
112 : "=r" (tmp), "=m" (*val)
113 : "0" (1), "m" (*val));
118 static inline gint32 InterlockedDecrement(volatile gint32 *val)
122 __asm__ __volatile__ ("lock; xaddl %0, %1"
123 : "=r" (tmp), "=m" (*val)
124 : "0" (-1), "m" (*val));
131 * http://msdn.microsoft.com/library/en-us/dnmag00/html/win320700.asp?frame=true
132 * for the reasons for using cmpxchg and a loop here.
134 * That url is no longer valid, but it's still in the google cache at the
135 * moment: http://www.google.com/search?q=cache:http://msdn.microsoft.com/library/en-us/dnmag00/html/win320700.asp?frame=true
137 * For the time being, http://msdn.microsoft.com/msdnmag/issues/0700/Win32/
138 * might work. Bet it will change soon enough though.
140 static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val)
144 __asm__ __volatile__ ("1:; lock; cmpxchgl %2, %0; jne 1b"
145 : "=m" (*val), "=a" (ret)
146 : "r" (new_val), "m" (*val), "a" (*val));
151 static inline gpointer InterlockedExchangePointer(volatile gpointer *val,
156 __asm__ __volatile__ ("1:; lock; "
163 : "=m" (*val), "=a" (ret)
164 : "r" (new_val), "m" (*val), "a" (*val));
169 static inline gint32 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
173 __asm__ __volatile__ ("lock; xaddl %0, %1"
174 : "=r" (ret), "=m" (*val)
175 : "0" (add), "m" (*val));
180 #elif (defined(sparc) || defined (__sparc__)) && defined(__GNUC__)
181 #define WAPI_ATOMIC_ASM
184 static inline gint32 InterlockedCompareExchange(volatile gint32 *_dest, gint32 _exch, gint32 _comp)
186 register volatile gint32 *dest asm("g1") = _dest;
187 register gint32 comp asm("o4") = _comp;
188 register gint32 exch asm("o5") = _exch;
190 __asm__ __volatile__(
191 /* cas [%%g1], %%o4, %%o5 */
194 : "0" (exch), "r" (dest), "r" (comp)
201 static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *_dest, gpointer _exch, gpointer _comp)
203 register volatile gpointer *dest asm("g1") = _dest;
204 register gpointer comp asm("o4") = _comp;
205 register gpointer exch asm("o5") = _exch;
207 __asm__ __volatile__(
209 /* casx [%%g1], %%o4, %%o5 */
212 /* cas [%%g1], %%o4, %%o5 */
216 : "0" (exch), "r" (dest), "r" (comp)
223 static inline gint32 InterlockedIncrement(volatile gint32 *_dest)
225 register volatile gint32 *dest asm("g1") = _dest;
226 register gint32 tmp asm("o4");
227 register gint32 ret asm("o5");
229 __asm__ __volatile__(
230 "1: ld [%%g1], %%o4\n\t"
231 " add %%o4, 1, %%o5\n\t"
232 /* cas [%%g1], %%o4, %%o5 */
233 " .word 0xdbe0500c\n\t"
234 " cmp %%o4, %%o5\n\t"
237 : "=&r" (tmp), "=&r" (ret)
245 static inline gint32 InterlockedDecrement(volatile gint32 *_dest)
247 register volatile gint32 *dest asm("g1") = _dest;
248 register gint32 tmp asm("o4");
249 register gint32 ret asm("o5");
251 __asm__ __volatile__(
252 "1: ld [%%g1], %%o4\n\t"
253 " sub %%o4, 1, %%o5\n\t"
254 /* cas [%%g1], %%o4, %%o5 */
255 " .word 0xdbe0500c\n\t"
256 " cmp %%o4, %%o5\n\t"
259 : "=&r" (tmp), "=&r" (ret)
267 static inline gint32 InterlockedExchange(volatile gint32 *_dest, gint32 exch)
269 register volatile gint32 *dest asm("g1") = _dest;
270 register gint32 tmp asm("o4");
271 register gint32 ret asm("o5");
273 __asm__ __volatile__(
274 "1: ld [%%g1], %%o4\n\t"
276 /* cas [%%g1], %%o4, %%o5 */
277 " .word 0xdbe0500c\n\t"
278 " cmp %%o4, %%o5\n\t"
281 : "=&r" (tmp), "=&r" (ret)
282 : "r" (dest), "r" (exch)
289 static inline gpointer InterlockedExchangePointer(volatile gpointer *_dest, gpointer exch)
291 register volatile gpointer *dest asm("g1") = _dest;
292 register gpointer tmp asm("o4");
293 register gpointer ret asm("o5");
295 __asm__ __volatile__(
297 "1: ldx [%%g1], %%o4\n\t"
299 "1: ld [%%g1], %%o4\n\t"
303 /* casx [%%g1], %%o4, %%o5 */
304 " .word 0xdbf0500c\n\t"
306 /* cas [%%g1], %%o4, %%o5 */
307 " .word 0xdbe0500c\n\t"
309 " cmp %%o4, %%o5\n\t"
312 : "=&r" (tmp), "=&r" (ret)
313 : "r" (dest), "r" (exch)
320 static inline gint32 InterlockedExchangeAdd(volatile gint32 *_dest, gint32 add)
322 register volatile gint32 *dest asm("g1") = _dest;
323 register gint32 tmp asm("o4");
324 register gint32 ret asm("o5");
326 __asm__ __volatile__(
327 "1: ld [%%g1], %%o4\n\t"
328 " add %%o4, %3, %%o5\n\t"
329 /* cas [%%g1], %%o4, %%o5 */
330 " .word 0xdbe0500c\n\t"
331 " cmp %%o4, %%o5\n\t"
333 " add %%o5, %3, %%o5"
334 : "=&r" (tmp), "=&r" (ret)
335 : "r" (dest), "r" (add)
343 #define WAPI_ATOMIC_ASM
346 InterlockedCompareExchange(volatile gint32 *dest,
347 gint32 exch, gint32 comp)
351 __asm__ __volatile__ ("\tLA\t1,%0\n"
354 : "+m" (*dest), "=&r" (old)
355 : "r" (exch), "r" (comp)
361 static inline gpointer
362 InterlockedCompareExchangePointer(volatile gpointer *dest,
363 gpointer exch, gpointer comp)
367 __asm__ __volatile__ ("\tLA\t1,%0\n"
370 : "+m" (*dest), "=&r" (old)
371 : "r" (exch), "r" (comp)
376 static inline gpointer
377 InterlockedCompareExchangePointer(volatile gpointer *dest,
383 __asm__ __volatile__ ("\tLA\t1,%0\n"
385 "\tCSG\t%1,%2,0(1)\n"
386 : "+m" (*dest), "=&r" (old)
387 : "r" (exch), "r" (comp)
396 InterlockedIncrement(volatile gint32 *val)
400 __asm__ __volatile__ ("\tLA\t2,%1\n"
407 : "=r" (tmp), "+m" (*val)
414 InterlockedIncrement(volatile gint32 *val)
418 __asm__ __volatile__ ("\tLA\t2,%1\n"
425 : "=r" (tmp), "+m" (*val)
434 InterlockedDecrement(volatile gint32 *val)
438 __asm__ __volatile__ ("\tLA\t2,%1\n"
445 : "=r" (tmp), "+m" (*val)
452 InterlockedDecrement(volatile gint32 *val)
456 __asm__ __volatile__ ("\tLA\t2,%1\n"
463 : "=r" (tmp), "+m" (*val)
471 InterlockedExchange(volatile gint32 *val, gint32 new_val)
475 __asm__ __volatile__ ("\tLA\t1,%0\n"
479 : "+m" (*val), "=&r" (ret)
487 static inline gpointer
488 InterlockedExchangePointer(volatile gpointer *val, gpointer new_val)
492 __asm__ __volatile__ ("\tLA\t1,%0\n"
496 : "+m" (*val), "=&r" (ret)
503 static inline gpointer
504 InterlockedExchangePointer(volatile gpointer *val, gpointer new_val)
508 __asm__ __volatile__ ("\tLA\t1,%0\n"
510 "\tCSG\t%1,%2,0(1)\n"
512 : "+m" (*val), "=&r" (ret)
522 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
526 __asm__ __volatile__ ("\tLA\t2,%1\n"
532 : "=&r" (ret), "+m" (*val)
540 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
544 __asm__ __volatile__ ("\tLA\t2,%1\n"
550 : "=&r" (ret), "+m" (*val)
558 #elif defined(__mono_ppc__)
559 #define WAPI_ATOMIC_ASM
561 #ifdef G_COMPILER_CODEWARRIOR
562 static inline gint32 InterlockedIncrement(volatile register gint32 *val)
564 gint32 result = 0, tmp;
565 register gint32 result = 0;
573 stwcx. result, 0, val
580 static inline gint32 InterlockedDecrement(register volatile gint32 *val)
582 register gint32 result = 0;
590 stwcx. result, 0, val
596 #define InterlockedCompareExchangePointer(dest,exch,comp) (void*)InterlockedCompareExchange((volatile gint32 *)(dest), (gint32)(exch), (gint32)(comp))
598 static inline gint32 InterlockedCompareExchange(volatile register gint32 *dest, register gint32 exch, register gint32 comp)
600 register gint32 tmp = 0;
615 static inline gint32 InterlockedExchange(register volatile gint32 *dest, register gint32 exch)
617 register gint32 tmp = 0;
629 #define InterlockedExchangePointer(dest,exch) (void*)InterlockedExchange((volatile gint32 *)(dest), (gint32)(exch))
632 #if defined(__mono_ppc64__) && !defined(__mono_ilp32__)
633 #define LDREGX "ldarx"
634 #define STREGCXD "stdcx."
635 #define CMPREG "cmpd"
637 #define LDREGX "lwarx"
638 #define STREGCXD "stwcx."
639 #define CMPREG "cmpw"
642 static inline gint32 InterlockedIncrement(volatile gint32 *val)
644 gint32 result = 0, tmp;
646 __asm__ __volatile__ ("\n1:\n\t"
647 "lwarx %0, 0, %2\n\t"
649 "stwcx. %1, 0, %2\n\t"
651 : "=&b" (result), "=&b" (tmp): "r" (val): "cc", "memory");
655 static inline gint32 InterlockedDecrement(volatile gint32 *val)
657 gint32 result = 0, tmp;
659 __asm__ __volatile__ ("\n1:\n\t"
660 "lwarx %0, 0, %2\n\t"
661 "addi %1, %0, -1\n\t"
662 "stwcx. %1, 0, %2\n\t"
664 : "=&b" (result), "=&b" (tmp): "r" (val): "cc", "memory");
668 static inline gpointer InterlockedCompareExchangePointer (volatile gpointer *dest,
669 gpointer exch, gpointer comp)
673 __asm__ __volatile__ ("\n1:\n\t"
674 LDREGX " %0, 0, %1\n\t"
677 STREGCXD " %3, 0, %1\n\t"
681 : "b" (dest), "r" (comp), "r" (exch): "cc", "memory");
685 static inline gint32 InterlockedCompareExchange(volatile gint32 *dest,
686 gint32 exch, gint32 comp) {
689 __asm__ __volatile__ ("\n1:\n\t"
690 "lwarx %0, 0, %1\n\t"
693 "stwcx. %3, 0, %1\n\t"
697 : "b" (dest), "r" (comp), "r" (exch): "cc", "memory");
701 static inline gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
705 __asm__ __volatile__ ("\n1:\n\t"
706 "lwarx %0, 0, %2\n\t"
707 "stwcx. %3, 0, %2\n\t"
709 : "=r" (tmp) : "0" (tmp), "b" (dest), "r" (exch): "cc", "memory");
713 static inline gpointer InterlockedExchangePointer (volatile gpointer *dest, gpointer exch)
717 __asm__ __volatile__ ("\n1:\n\t"
718 LDREGX " %0, 0, %2\n\t"
719 STREGCXD " %3, 0, %2\n\t"
721 : "=r" (tmp) : "0" (tmp), "b" (dest), "r" (exch): "cc", "memory");
725 static inline gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
728 __asm__ __volatile__ ("\n1:\n\t"
729 "lwarx %0, 0, %2\n\t"
731 "stwcx. %1, 0, %2\n\t"
733 : "=&r" (result), "=&r" (tmp)
734 : "r" (dest), "r" (add) : "cc", "memory");
742 #endif /* !G_COMPILER_CODEWARRIOR */
744 #elif defined(__arm__)
745 #define WAPI_ATOMIC_ASM
747 static inline gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch, gint32 comp)
751 __asm__ __volatile__ ( "0:\n\t"
756 "swp %0, %3, [%2]\n\t"
758 "swpne %3, %0, [%2]\n\t"
761 : "=&r" (a), "=&r" (b)
762 : "r" (dest), "r" (exch), "r" (comp)
768 static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp)
772 __asm__ __volatile__ ( "0:\n\t"
777 "swpeq %0, %3, [%2]\n\t"
779 "swpne %3, %0, [%2]\n\t"
782 : "=&r" (a), "=&r" (b)
783 : "r" (dest), "r" (exch), "r" (comp)
789 static inline gint32 InterlockedIncrement(volatile gint32 *dest)
793 __asm__ __volatile__ ( "0:\n\t"
796 "swp %2, %1, [%3]\n\t"
798 "swpne %1, %2, [%3]\n\t"
800 : "=&r" (a), "=&r" (b), "=&r" (c)
801 : "r" (dest), "r" (1)
807 static inline gint32 InterlockedDecrement(volatile gint32 *dest)
811 __asm__ __volatile__ ( "0:\n\t"
814 "swp %2, %1, [%3]\n\t"
816 "swpne %1, %2, [%3]\n\t"
818 : "=&r" (a), "=&r" (b), "=&r" (c)
819 : "r" (dest), "r" (-1)
825 static inline gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
829 __asm__ __volatile__ ( "swp %0, %2, [%1]"
831 : "r" (dest), "r" (exch));
836 static inline gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch)
840 __asm__ __volatile__ ( "swp %0, %2, [%1]"
842 : "r" (dest), "r" (exch));
847 static inline gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
851 __asm__ __volatile__ ( "0:\n\t"
854 "swp %2, %1, [%3]\n\t"
856 "swpne %1, %2, [%3]\n\t"
858 : "=&r" (a), "=&r" (b), "=&r" (c)
859 : "r" (dest), "r" (add)
865 #elif defined(__ia64__)
866 #define WAPI_ATOMIC_ASM
868 #ifdef __INTEL_COMPILER
869 #include <ia64intrin.h>
872 static inline gint32 InterlockedCompareExchange(gint32 volatile *dest,
873 gint32 exch, gint32 comp)
878 #ifdef __INTEL_COMPILER
879 old = _InterlockedCompareExchange (dest, exch, comp);
881 /* cmpxchg4 zero extends the value read from memory */
882 real_comp = (guint64)(guint32)comp;
883 asm volatile ("mov ar.ccv = %2 ;;\n\t"
884 "cmpxchg4.acq %0 = [%1], %3, ar.ccv\n\t"
885 : "=r" (old) : "r" (dest), "r" (real_comp), "r" (exch));
891 static inline gpointer InterlockedCompareExchangePointer(gpointer volatile *dest,
892 gpointer exch, gpointer comp)
896 #ifdef __INTEL_COMPILER
897 old = _InterlockedCompareExchangePointer (dest, exch, comp);
899 asm volatile ("mov ar.ccv = %2 ;;\n\t"
900 "cmpxchg8.acq %0 = [%1], %3, ar.ccv\n\t"
901 : "=r" (old) : "r" (dest), "r" (comp), "r" (exch));
907 static inline gint32 InterlockedIncrement(gint32 volatile *val)
909 #ifdef __INTEL_COMPILER
910 return _InterlockedIncrement (val);
916 } while (InterlockedCompareExchange (val, old + 1, old) != old);
922 static inline gint32 InterlockedDecrement(gint32 volatile *val)
924 #ifdef __INTEL_COMPILER
925 return _InterlockedDecrement (val);
931 } while (InterlockedCompareExchange (val, old - 1, old) != old);
937 static inline gint32 InterlockedExchange(gint32 volatile *dest, gint32 new_val)
939 #ifdef __INTEL_COMPILER
940 return _InterlockedExchange (dest, new_val);
946 } while (InterlockedCompareExchange (dest, new_val, res) != res);
952 static inline gpointer InterlockedExchangePointer(gpointer volatile *dest, gpointer new_val)
954 #ifdef __INTEL_COMPILER
955 return (gpointer)_InterlockedExchange64 ((gint64*)dest, (gint64)new_val);
961 } while (InterlockedCompareExchangePointer (dest, new_val, res) != res);
967 static inline gint32 InterlockedExchangeAdd(gint32 volatile *val, gint32 add)
971 #ifdef __INTEL_COMPILER
972 old = _InterlockedExchangeAdd (val, add);
976 } while (InterlockedCompareExchange (val, old + add, old) != old);
982 #elif defined(__alpha__)
983 #define WAPI_ATOMIC_ASM
985 static inline gint32 InterlockedCompareExchange(volatile gint32 *dest,
986 gint32 exch, gint32 comp)
988 gint32 old, temp, temp2;
989 long compq = comp, exchq = exch;
991 __asm__ __volatile__ (
994 " cmpeq %2, %5, %3\n"
995 " cmovne %3, %4, %2\n"
998 : "=m" (*dest), "=&r" (old), "=&r" (temp), "=&r" (temp2)
999 : "r" (exchq), "r" (compq), "m" (*dest));
1003 static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp)
1005 gpointer old, temp, temp2;
1007 __asm__ __volatile__ (
1010 " cmpeq %2, %5, %3\n"
1011 " cmovne %3, %4, %2\n"
1014 : "=m" (*dest), "=&r" (old), "=&r" (temp), "=&r" (temp2)
1015 : "r" (exch), "r" (comp), "m" (*dest));
1019 static inline gint32 InterlockedIncrement(volatile gint32 *val)
1023 __asm__ __volatile__ (
1025 " addl %0, %3, %0\n"
1029 : "=&r" (temp), "=m" (*val), "=r" (cur)
1030 : "Ir" (1), "m" (*val));
1034 static inline gint32 InterlockedDecrement(volatile gint32 *val)
1038 __asm__ __volatile__ (
1040 " subl %0, %3, %0\n"
1044 : "=&r" (temp), "=m" (*val), "=r" (cur)
1045 : "Ir" (1), "m" (*val));
1049 static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val)
1053 __asm__ __volatile__ (
1058 : "=m" (*val), "=&r" (ret), "=&r" (temp)
1059 : "r" (new_val), "m" (*val));
1063 static inline gpointer InterlockedExchangePointer(volatile gpointer *val, gpointer new_val)
1067 __asm__ __volatile__ (
1072 : "=m" (*val), "=&r" (ret), "=&r" (temp)
1073 : "r" (new_val), "m" (*val));
1077 static inline gint32 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
1081 __asm__ __volatile__ (
1084 " addl %2, %3, %2\n"
1087 : "=m" (*val), "=&r" (ret), "=&r" (temp)
1088 : "r" (add), "m" (*val));
1093 #elif defined(__mips__)
1094 #define WAPI_ATOMIC_ASM
1096 static inline gint32 InterlockedIncrement(volatile gint32 *val)
1098 gint32 tmp, result = 0;
1100 __asm__ __volatile__ (" .set mips32\n"
1106 : "=&r" (result), "=&r" (tmp), "=m" (*val)
1111 static inline gint32 InterlockedDecrement(volatile gint32 *val)
1113 gint32 tmp, result = 0;
1115 __asm__ __volatile__ (" .set mips32\n"
1121 : "=&r" (result), "=&r" (tmp), "=m" (*val)
1126 #define InterlockedCompareExchangePointer(dest,exch,comp) InterlockedCompareExchange((volatile gint32 *)(dest), (gint32)(exch), (gint32)(comp))
1128 static inline gint32 InterlockedCompareExchange(volatile gint32 *dest,
1129 gint32 exch, gint32 comp) {
1132 __asm__ __volatile__ (" .set mips32\n"
1139 : "=&r" (old), "=&r" (tmp), "=m" (*dest)
1140 : "m" (*dest), "r" (exch), "r" (comp));
1144 static inline gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
1148 __asm__ __volatile__ (" .set mips32\n"
1154 : "=&r" (result), "=&r" (tmp), "=m" (*dest)
1155 : "m" (*dest), "r" (exch));
1158 #define InterlockedExchangePointer(dest,exch) InterlockedExchange((volatile gint32 *)(dest), (gint32)(exch))
1160 static inline gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
1164 __asm__ __volatile__ (" .set mips32\n"
1166 " addu %1, %0, %4\n"
1170 : "=&r" (result), "=&r" (tmp), "=m" (*dest)
1171 : "m" (*dest), "r" (add));
1177 extern gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch, gint32 comp);
1178 extern gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp);
1179 extern gint32 InterlockedIncrement(volatile gint32 *dest);
1180 extern gint32 InterlockedDecrement(volatile gint32 *dest);
1181 extern gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch);
1182 extern gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch);
1183 extern gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add);
1185 #if defined(__hppa__)
1186 #define WAPI_ATOMIC_ASM
1191 #endif /* _WAPI_ATOMIC_H_ */