1 /* ----------------------------------------------------------------------------
3 * (c) The GHC Team, 2005
5 * Macros for SMP support
7 * -------------------------------------------------------------------------- */
12 /* SMP is currently not compatible with the following options:
17 * and unregisterised builds.
22 #if defined(PROFILING) || defined(TICKY_TICKY)
23 #error Build options incompatible with SMP.
27 * XCHG - the atomic exchange instruction. Used for locking closures
28 * during updates (see lockClosure() below) and the MVar primops.
30 * NB: the xchg instruction is implicitly locked, so we do not need
34 xchg(StgPtr p, StgWord w)
38 __asm__ __volatile__ (
40 :"+r" (result), "+m" (*p)
41 : /* no input-only operands */
47 * CMPXCHG - the single-word atomic compare-and-exchange instruction. Used
48 * in the STM implementation.
51 cas(StgVolatilePtr p, StgWord o, StgWord n)
53 __asm__ __volatile__ (
55 :"=a"(o), "=m" (*(volatile unsigned int *)p)
61 * Write barrier - ensure that all preceding writes have happened
62 * before all following writes.
64 * We need to tell both the compiler AND the CPU about the barrier.
65 * This is a brute force solution; better results might be obtained by
66 * using volatile type declarations to get fine-grained ordering
67 * control in C, and optionally a memory barrier instruction on CPUs
68 * that require it (not x86 or x86_64).
72 #if i386_HOST_ARCH || x86_64_HOST_ARCH
73 __asm__ __volatile__ ("" : : : "memory");
75 #error memory barriers unimplemented on this architecture
80 * Locking/unlocking closures
82 * This is used primarily in the implementation of MVars.
84 #define SPIN_COUNT 4000
86 INLINE_HEADER StgInfoTable *
87 lockClosure(StgClosure *p)
89 #if i386_HOST_ARCH || x86_64_HOST_ARCH
94 info = xchg((P_)&p->header.info, (W_)&stg_WHITEHOLE_info);
95 if (info != (W_)&stg_WHITEHOLE_info) return (StgInfoTable *)info;
96 } while (++i < SPIN_COUNT);
105 unlockClosure(StgClosure *p, StgInfoTable *info)
107 #if i386_HOST_ARCH || x86_64_HOST_ARCH
108 // This is a strictly ordered write, so we need a wb():
110 p->header.info = info;
118 #define wb() /* nothing */
120 INLINE_HEADER StgWord
121 xchg(StgPtr p, StgWord w)