merge GHC HEAD
[ghc-hetmet.git] / includes / stg / SMP.h
index 5d9d801..52fd6f1 100644 (file)
@@ -1,9 +1,14 @@
 /* ----------------------------------------------------------------------------
  *
- * (c) The GHC Team, 2005-2008
+ * (c) The GHC Team, 2005-2009
  *
  * Macros for multi-CPU support
  *
+ * Do not #include this file directly: #include "Rts.h" instead.
+ *
+ * To understand the structure of the RTS headers, see the wiki:
+ *   http://hackage.haskell.org/trac/ghc/wiki/Commentary/SourceTree/Includes
+ *
  * -------------------------------------------------------------------------- */
 
 #ifndef SMP_H
@@ -59,6 +64,13 @@ EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p);
  */
 EXTERN_INLINE StgWord atomic_dec(StgVolatilePtr p);
 
+/*
+ * Busy-wait nop: this is a hint to the CPU that we are currently in a
+ * busy-wait loop waiting for another CPU to change something.  On a
+ * hypertreaded CPU it should yield to another thread, for example.
+ */
+EXTERN_INLINE void busy_wait_nop(void);
+
 #endif // !IN_STG_CODE
 
 /*
@@ -211,6 +223,17 @@ atomic_dec(StgVolatilePtr p)
 #endif
 }
 
+EXTERN_INLINE void
+busy_wait_nop(void)
+{
+#if defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH)
+    __asm__ __volatile__ ("rep; nop");
+    //
+#else
+    // nothing
+#endif
+}
+
 #endif // !IN_STG_CODE
 
 /*
@@ -270,6 +293,12 @@ load_load_barrier(void) {
 #endif
 }
 
+// Load a pointer from a memory location that might be being modified
+// concurrently.  This prevents the compiler from optimising away
+// multiple loads of the memory location, as it might otherwise do in
+// a busy wait loop for example.
+#define VOLATILE_LOAD(p) (*((StgVolatilePtr)(p)))
+
 /* ---------------------------------------------------------------------- */
 #else /* !THREADED_RTS */
 
@@ -277,6 +306,7 @@ load_load_barrier(void) {
 #define store_load_barrier() /* nothing */
 #define load_load_barrier()  /* nothing */
 
+#if !IN_STG_CODE || IN_STGCRUN
 INLINE_HEADER StgWord
 xchg(StgPtr p, StgWord w)
 {
@@ -285,7 +315,8 @@ xchg(StgPtr p, StgWord w)
     return old;
 }
 
-STATIC_INLINE StgWord
+EXTERN_INLINE StgWord cas(StgVolatilePtr p, StgWord o, StgWord n);
+EXTERN_INLINE StgWord
 cas(StgVolatilePtr p, StgWord o, StgWord n)
 {
     StgWord result;
@@ -307,6 +338,9 @@ atomic_dec(StgVolatilePtr p)
 {
     return --(*p);
 }
+#endif
+
+#define VOLATILE_LOAD(p) ((StgWord)*((StgWord*)(p)))
 
 #endif /* !THREADED_RTS */