[project @ 2005-05-24 15:43:32 by simonmar]
[ghc-hetmet.git] / ghc / includes / SMP.h
1 /* ----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 2005
4  *
5  * Macros for SMP support
6  *
7  * -------------------------------------------------------------------------- */
8
9 #ifndef SMP_H
10 #define SMP_H
11
12 /* SMP is currently not compatible with the following options:
13  *
14  *      INTERPRETER
15  *      PROFILING
16  *      TICKY_TICKY
17  *      and unregisterised builds.
18  */
19
20 #if defined(SMP)
21
22 #if  defined(PROFILING)  || defined(TICKY_TICKY)
23 #error Build options incompatible with SMP.
24 #endif
25
26 /* 
27  * XCHG - the atomic exchange instruction.  Used for locking closures
28  * during updates (see LOCK_CLOSURE below) and the MVar primops.
29  */
30 INLINE_HEADER StgWord
31 xchg(StgPtr p, StgWord w)
32 {
33     StgWord result;
34     result = w;
35     __asm__ __volatile__ (
36           "xchg %1,%0"
37           :"+r" (result), "+m" (*p)
38           : /* no input-only operands */
39         );
40     return result;
41 }
42
43 INLINE_HEADER StgInfoTable *
44 lockClosure(StgClosure *p)
45 {
46 #if i386_HOST_ARCH || x86_64_HOST_ARCH
47     StgWord info;
48     do {
49         info = xchg((P_)&p->header.info, (W_)&stg_WHITEHOLE_info);
50         if (info != (W_)&stg_WHITEHOLE_info) return (StgInfoTable *)info;
51         yieldThread();
52     } while (1);
53 #else
54    ACQUIRE_SM_LOCK
55 #endif
56 }
57
58 INLINE_HEADER void
59 unlockClosure(StgClosure *p, StgInfoTable *info)
60 {
61 #if i386_HOST_ARCH || x86_64_HOST_ARCH
62     // This is safe enough, because lockClosure() does the memory barrier:
63     p->header.info = info;
64 #else
65     RELEASE_SM_LOCK;
66 #endif
67 }
68
69 #endif /* SMP */
70
71 #endif /* SMP_H */