[project @ 2001-02-08 14:36:21 by simonmar]
[ghc-hetmet.git] / ghc / includes / SMP.h
1 /* ----------------------------------------------------------------------------
2  * $Id: SMP.h,v 1.2 2001/02/08 14:36:21 simonmar Exp $
3  *
4  * (c) The GHC Team, 1999
5  *
6  * Macros for SMP support
7  *
8  * -------------------------------------------------------------------------- */
9
10 #ifndef SMP_H
11 #define SMP_H
12
13 /* SMP is currently not compatible with the following options:
14  *
15  *      INTERPRETER
16  *      PROFILING
17  *      TICKY_TICKY
18  *      and unregisterised builds.
19  */
20
21 #if defined(SMP)
22
23 #if    defined(INTERPRETER) \
24      || defined(PROFILING)  \
25      || defined(TICKY_TICKY)
26 #error Build options incompatible with SMP.
27 #endif
28
29 /*
30  * CMPXCHG - this instruction is the standard "test & set".  We use it
31  * for locking closures in the thunk and blackhole entry code.  If the
32  * closure is already locked, or has an unexpected info pointer
33  * (because another thread is altering it in parallel), we just jump
34  * to the new entry point.
35  */
36 #if defined(i386_TARGET_ARCH) && defined(TABLES_NEXT_TO_CODE)
37 #define CMPXCHG(p, cmp, new)                    \
38   __asm__ __volatile__ (                        \
39           "lock ; cmpxchg %1, %0\n"             \
40           "\tje 1f\n"                           \
41           "\tjmp *%%eax\n"                      \
42           "\t1:\n"                              \
43           : /* no outputs */                    \
44           : "m" (p), "r" (new), "r" (cmp)       \
45           )
46
47 /* 
48  * XCHG - the atomic exchange instruction.  Used for locking closures
49  * during updates (see LOCK_CLOSURE below) and the MVar primops.
50  */
51 #define XCHG(reg, obj)                          \
52   __asm__ __volatile__ (                        \
53           "xchgl %1,%0"                         \
54           :"+r" (reg), "+m" (obj)               \
55           : /* no input-only operands */        \
56           )
57
58 #else
59 #error SMP macros not defined for this architecture
60 #endif
61
62 /*
63  * LOCK_CLOSURE locks the specified closure, busy waiting for any
64  * existing locks to be cleared.
65  */
66 #define LOCK_CLOSURE(c)                                 \
67   ({                                                    \
68     const StgInfoTable *__info;                         \
69     __info = &stg_WHITEHOLE_info;                       \
70     do {                                                \
71       XCHG(__info,((StgClosure *)(c))->header.info);    \
72     } while (__info == &stg_WHITEHOLE_info);            \
73     __info;                                             \
74   })
75
76 #define LOCK_THUNK(__info)                              \
77   CMPXCHG(R1.cl->header.info, __info, &stg_WHITEHOLE_info);
78
79 #define ACQUIRE_LOCK(mutex) pthread_mutex_lock(mutex);
80 #define RELEASE_LOCK(mutex) pthread_mutex_unlock(mutex);
81
82 #else /* !SMP */
83
84 #define LOCK_CLOSURE(c)     /* nothing */
85 #define LOCK_THUNK(__info)  /* nothing */
86 #define ACQUIRE_LOCK(mutex) /* nothing */
87 #define RELEASE_LOCK(mutex) /* nothing */
88
89 #endif /* SMP */
90
91 #endif /* SMP_H */