1 /* ----------------------------------------------------------------------------
3 * (c) The GHC Team, 2005
5 * Macros for THREADED_RTS support
7 * -------------------------------------------------------------------------- */
9 #ifndef SMPCLOSUREOPS_H
10 #define SMPCLOSUREOPS_H
12 #if defined(THREADED_RTS)
14 /* -----------------------------------------------------------------------------
15 * Locking/unlocking closures
17 * This is used primarily in the implementation of MVars.
18 * -------------------------------------------------------------------------- */
20 #define SPIN_COUNT 4000
22 #ifdef KEEP_LOCKCLOSURE
23 // We want a callable copy of lockClosure() so that we can refer to it
24 // from .cmm files compiled using the native codegen.
25 extern StgInfoTable *lockClosure(StgClosure *p);
31 lockClosure(StgClosure *p)
37 info = xchg((P_)(void *)&p->header.info, (W_)&stg_WHITEHOLE_info);
38 if (info != (W_)&stg_WHITEHOLE_info) return (StgInfoTable *)info;
39 } while (++i < SPIN_COUNT);
45 unlockClosure(StgClosure *p, const StgInfoTable *info)
47 // This is a strictly ordered write, so we need a write_barrier():
49 p->header.info = info;
52 #else /* !THREADED_RTS */
54 INLINE_HEADER StgInfoTable *
55 lockClosure(StgClosure *p)
56 { return (StgInfoTable *)p->header.info; }
59 unlockClosure(StgClosure *p STG_UNUSED, const StgInfoTable *info STG_UNUSED)
62 #endif /* THREADED_RTS */
64 // Handy specialised versions of lockClosure()/unlockClosure()
65 INLINE_HEADER void lockTSO(StgTSO *tso)
66 { lockClosure((StgClosure *)tso); }
68 INLINE_HEADER void unlockTSO(StgTSO *tso)
69 { unlockClosure((StgClosure*)tso, (const StgInfoTable *)&stg_TSO_info); }
71 #endif /* SMPCLOSUREOPS_H */