#if defined(THREADED_RTS)
-#if defined(TICKY_TICKY)
+#if defined(TICKY_TICKY)
#error Build options incompatible with THREADED_RTS.
#endif
*/
EXTERN_INLINE StgWord cas(StgVolatilePtr p, StgWord o, StgWord n);
+/*
+ * Atomic increment
+ *
+ * atomic_inc(p) {
+ * return ++(*p);
+ * }
+ */
+EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p);
+
+/*
+ * Atomic decrement
+ *
+ * atomic_dec(p) {
+ * return --(*p);
+ * }
+ */
+EXTERN_INLINE StgWord atomic_dec(StgVolatilePtr p);
+
#endif // !IN_STG_CODE
/*
#endif
}
+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
+}
+
#endif // !IN_STG_CODE
/*
#elif powerpc_HOST_ARCH
__asm__ __volatile__ ("lwsync" : : : "memory");
#elif sparc_HOST_ARCH
- /* Sparc in TSO mode does not require write/write barriers. */
+ /* Sparc in TSO mode does not require store/store barriers. */
__asm__ __volatile__ ("" : : : "memory");
#elif !defined(WITHSMP)
return;
#elif x86_64_HOST_ARCH
__asm__ __volatile__ ("lock; addq $0,0(%%rsp)" : : : "memory");
#elif powerpc_HOST_ARCH
- __asm__ __volatile__ ("msync" : : : "memory");
+ __asm__ __volatile__ ("sync" : : : "memory");
#elif sparc_HOST_ARCH
- /* Sparc in TSO mode does not require write/write barriers. */
- __asm__ __volatile__ ("membar" : : : "memory");
+ __asm__ __volatile__ ("membar #StoreLoad" : : : "memory");
#elif !defined(WITHSMP)
return;
#else
#elif powerpc_HOST_ARCH
__asm__ __volatile__ ("lwsync" : : : "memory");
#elif sparc_HOST_ARCH
- /* Sparc in TSO mode does not require write/write barriers. */
+ /* Sparc in TSO mode does not require load/load barriers. */
__asm__ __volatile__ ("" : : : "memory");
#elif !defined(WITHSMP)
return;
return result;
}
+INLINE_HEADER StgWord
+atomic_inc(StgVolatilePtr p)
+{
+ return ++(*p);
+}
+
+INLINE_HEADER StgWord
+atomic_dec(StgVolatilePtr p)
+{
+ return --(*p);
+}
+
#endif /* !THREADED_RTS */
#endif /* SMP_H */