/* ----------------------------------------------------------------------------
*
- * (c) The GHC Team, 1999
+ * (c) The GHC Team, 2005
*
* Macros for SMP support
*
#error Build options incompatible with SMP.
#endif
-/*
- * CMPXCHG - this instruction is the standard "test & set". We use it
- * for locking closures in the thunk and blackhole entry code. If the
- * closure is already locked, or has an unexpected info pointer
- * (because another thread is altering it in parallel), we just jump
- * to the new entry point.
- */
-#if defined(i386_HOST_ARCH) && defined(TABLES_NEXT_TO_CODE)
-#define CMPXCHG(p, cmp, new) \
- __asm__ __volatile__ ( \
- "lock ; cmpxchg %1, %0\n" \
- "\tje 1f\n" \
- "\tjmp *%%eax\n" \
- "\t1:\n" \
- : /* no outputs */ \
- : "m" (p), "r" (new), "r" (cmp) \
- )
-
/*
* XCHG - the atomic exchange instruction. Used for locking closures
* during updates (see LOCK_CLOSURE below) and the MVar primops.
*/
-#define XCHG(reg, obj) \
- __asm__ __volatile__ ( \
- "xchgl %1,%0" \
- :"+r" (reg), "+m" (obj) \
- : /* no input-only operands */ \
- )
-
+INLINE_HEADER StgWord
+xchg(StgPtr p, StgWord w)
+{
+ StgWord result;
+ result = w;
+ __asm__ __volatile__ (
+ "xchgl %1,%0"
+ :"+r" (result), "+m" (*p)
+ : /* no input-only operands */
+ );
+ return result;
+}
+
+INLINE_HEADER StgInfoTable *
+lockClosure(StgClosure *p)
+{
+ StgWord info;
+#if 0
+ do {
+ info = xchg((P_)&p->header.info, (W_)&stg_WHITEHOLE_info);
+ if (info != (W_)&stg_WHITEHOLE_info) return (StgInfoTable *)info;
+ yieldThread();
+ } while (1);
#else
-#error SMP macros not defined for this architecture
+ info = p->header.info;
#endif
-
-/*
- * LOCK_CLOSURE locks the specified closure, busy waiting for any
- * existing locks to be cleared.
- */
-#define LOCK_CLOSURE(c) \
- ({ \
- const StgInfoTable *__info; \
- __info = &stg_WHITEHOLE_info; \
- do { \
- XCHG(__info,((StgClosure *)(c))->header.info); \
- } while (__info == &stg_WHITEHOLE_info); \
- __info; \
- })
-
-#define LOCK_THUNK(__info) \
- CMPXCHG(R1.cl->header.info, __info, &stg_WHITEHOLE_info);
-
-#else /* !SMP */
-
-#define LOCK_CLOSURE(c) /* nothing */
-#define LOCK_THUNK(__info) /* nothing */
+}
#endif /* SMP */