+EXTERN_INLINE StgWord
+atomic_inc(StgVolatilePtr p)
+{
+#if defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH)
+ StgWord r;
+ r = 1;
+ __asm__ __volatile__ (
+ "lock\nxadd %0,%1":
+ "+r" (r), "+m" (*p):
+ );
+ return r+1;
+#else
+ StgWord old, new;
+ do {
+ old = *p;
+ new = old + 1;
+ } while (cas(p, old, new) != old);
+ return new;
+#endif
+}
+
+EXTERN_INLINE StgWord
+atomic_dec(StgVolatilePtr p)
+{
+#if defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH)
+ StgWord r;
+ r = (StgWord)-1;
+ __asm__ __volatile__ (
+ "lock\nxadd %0,%1":
+ "+r" (r), "+m" (*p):
+ );
+ return r-1;
+#else
+ StgWord old, new;
+ do {
+ old = *p;
+ new = old - 1;
+ } while (cas(p, old, new) != old);
+ return new;
+#endif
+}
+