* Unregisterised builds are ok, but only 1 CPU supported.
*/
-#ifdef CMINUSMINUS
-
-#define unlockClosure(ptr,info) \
- prim %write_barrier() []; \
- StgHeader_info(ptr) = info;
-
-#else
-
#if defined(THREADED_RTS)
#if defined(TICKY_TICKY)
Atomic operations
------------------------------------------------------------------------- */
+#if !IN_STG_CODE
+// We only want write_barrier() declared in .hc files. Defining the
+// other inline functions here causes type mismatch errors from gcc,
+// because the generated C code is assuming that there are no
+// prototypes in scope.
+
/*
* The atomic exchange operation: xchg(p,w) exchanges the value
* pointed to by p with the value w, returning the old value.
*/
EXTERN_INLINE StgWord cas(StgVolatilePtr p, StgWord o, StgWord n);
+#endif // !IN_STG_CODE
+
/*
* Prevents write operations from moving across this call in either
* direction.
*/
EXTERN_INLINE void write_barrier(void);
+/*
+ * Prevents loads from moving before earlier stores.
+ */
+EXTERN_INLINE void store_load_barrier(void);
+
/* ----------------------------------------------------------------------------
Implementations
------------------------------------------------------------------------- */
+
+#if !IN_STG_CODE
+
/*
* NB: the xchg instruction is implicitly locked, so we do not need
* a lock prefix here.
#endif
}
+#endif // !IN_STG_CODE
+
/*
* Write barrier - ensure that all preceding writes have happened
* before all following writes.
#endif
}
+EXTERN_INLINE void
+store_load_barrier(void) {
+#if i386_HOST_ARCH
+ __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory");
+#elif x86_64_HOST_ARCH
+ __asm__ __volatile__ ("lock; addq $0,0(%%rsp)" : : : "memory");
+#elif powerpc_HOST_ARCH
+ __asm__ __volatile__ ("msync" : : : "memory");
+#elif sparc_HOST_ARCH
+ /* Sparc in TSO mode does not require write/write barriers. */
+ __asm__ __volatile__ ("membar" : : : "memory");
+#elif !defined(WITHSMP)
+ return;
+#else
+#error memory barriers unimplemented on this architecture
+#endif
+}
+
/* ---------------------------------------------------------------------- */
#else /* !THREADED_RTS */
#define write_barrier() /* nothing */
+#define store_load_barrier() /* nothing */
+
INLINE_HEADER StgWord
xchg(StgPtr p, StgWord w)
{
return old;
}
-#endif /* !THREADED_RTS */
+STATIC_INLINE StgWord
+cas(StgVolatilePtr p, StgWord o, StgWord n)
+{
+ StgWord result;
+ result = *p;
+ if (result == o) {
+ *p = n;
+ }
+ return result;
+}
-#endif /* CMINUSMINUS */
+#endif /* !THREADED_RTS */
#endif /* SMP_H */