diff options
author | Nicolas Frisby <nicolas.frisby@gmail.com> | 2013-08-22 15:00:41 -0500 |
---|---|---|
committer | Nicolas Frisby <nicolas.frisby@gmail.com> | 2013-08-22 15:00:54 -0500 |
commit | 84f9927c1a04b8e35b97101771d8f6d625643d9b (patch) | |
tree | 050d7265a24fa1ff9aecc4081bb01bc444520587 /includes/rts/storage/SMPClosureOps.h | |
parent | 2eaf46fb1bb8c661c03f3e5e80622207ef2509d9 (diff) | |
parent | c24be4b761df558d9edc9c0b1554bb558c261b14 (diff) | |
download | haskell-late-dmd.tar.gz |
merged master into late-dmdlate-dmd
Diffstat (limited to 'includes/rts/storage/SMPClosureOps.h')
-rw-r--r-- | includes/rts/storage/SMPClosureOps.h | 77 |
1 files changed, 57 insertions, 20 deletions
diff --git a/includes/rts/storage/SMPClosureOps.h b/includes/rts/storage/SMPClosureOps.h index 39349874f7..a8ebb5d0ed 100644 --- a/includes/rts/storage/SMPClosureOps.h +++ b/includes/rts/storage/SMPClosureOps.h @@ -11,13 +11,27 @@ #ifdef CMINUSMINUS +/* Lock closure, equivalent to ccall lockClosure but the condition is inlined. + * Arguments are swapped for uniformity with unlockClosure. */ +#if defined(THREADED_RTS) +#define LOCK_CLOSURE(closure, info) \ + if (CInt[n_capabilities] == 1 :: CInt) { \ + info = GET_INFO(closure); \ + } else { \ + ("ptr" info) = ccall reallyLockClosure(closure "ptr"); \ + } +#else +#define LOCK_CLOSURE(closure, info) info = GET_INFO(closure) +#endif + #define unlockClosure(ptr,info) \ prim_write_barrier; \ - StgHeader_info(ptr) = info; + StgHeader_info(ptr) = info; #else -EXTERN_INLINE StgInfoTable *lockClosure(StgClosure *p); +INLINE_HEADER StgInfoTable *lockClosure(StgClosure *p); +EXTERN_INLINE StgInfoTable *reallyLockClosure(StgClosure *p); EXTERN_INLINE StgInfoTable *tryLockClosure(StgClosure *p); EXTERN_INLINE void unlockClosure(StgClosure *p, const StgInfoTable *info); @@ -29,35 +43,58 @@ EXTERN_INLINE void unlockClosure(StgClosure *p, const StgInfoTable *info); * This is used primarily in the implementation of MVars. * -------------------------------------------------------------------------- */ -// We want a callable copy of lockClosure() so that we can refer to it -// from .cmm files compiled using the native codegen. -EXTERN_INLINE StgInfoTable *lockClosure(StgClosure *p) +// We want a callable copy of reallyLockClosure() so that we can refer to it +// from .cmm files compiled using the native codegen, so these are given +// EXTERN_INLINE. C-- should use LOCK_CLOSURE not lockClosure, so we've +// kept it INLINE_HEADER. +EXTERN_INLINE StgInfoTable *reallyLockClosure(StgClosure *p) { StgWord info; do { - nat i = 0; - do { - info = xchg((P_)(void *)&p->header.info, (W_)&stg_WHITEHOLE_info); - if (info != (W_)&stg_WHITEHOLE_info) return (StgInfoTable *)info; - } while (++i < SPIN_COUNT); - yieldThread(); + nat i = 0; + do { + info = xchg((P_)(void *)&p->header.info, (W_)&stg_WHITEHOLE_info); + if (info != (W_)&stg_WHITEHOLE_info) return (StgInfoTable *)info; + } while (++i < SPIN_COUNT); + yieldThread(); } while (1); } +INLINE_HEADER StgInfoTable *lockClosure(StgClosure *p) +{ + if (n_capabilities == 1) { + return (StgInfoTable *)p->header.info; + } + else { + return reallyLockClosure(p); + } +} + +// ToDo: consider splitting tryLockClosure into reallyTryLockClosure, +// same as lockClosure EXTERN_INLINE StgInfoTable *tryLockClosure(StgClosure *p) { StgWord info; - info = xchg((P_)(void *)&p->header.info, (W_)&stg_WHITEHOLE_info); - if (info != (W_)&stg_WHITEHOLE_info) { - return (StgInfoTable *)info; - } else { - return NULL; + if (n_capabilities == 1) { + return (StgInfoTable *)p->header.info; + } + else { + info = xchg((P_)(void *)&p->header.info, (W_)&stg_WHITEHOLE_info); + if (info != (W_)&stg_WHITEHOLE_info) { + return (StgInfoTable *)info; + } else { + return NULL; + } } } #else /* !THREADED_RTS */ EXTERN_INLINE StgInfoTable * +reallyLockClosure(StgClosure *p) +{ return (StgInfoTable *)p->header.info; } + +INLINE_HEADER StgInfoTable * lockClosure(StgClosure *p) { return (StgInfoTable *)p->header.info; } @@ -75,12 +112,12 @@ EXTERN_INLINE void unlockClosure(StgClosure *p, const StgInfoTable *info) } // Handy specialised versions of lockClosure()/unlockClosure() -EXTERN_INLINE void lockTSO(StgTSO *tso); -EXTERN_INLINE void lockTSO(StgTSO *tso) +INLINE_HEADER void lockTSO(StgTSO *tso); +INLINE_HEADER void lockTSO(StgTSO *tso) { lockClosure((StgClosure *)tso); } -EXTERN_INLINE void unlockTSO(StgTSO *tso); -EXTERN_INLINE void unlockTSO(StgTSO *tso) +INLINE_HEADER void unlockTSO(StgTSO *tso); +INLINE_HEADER void unlockTSO(StgTSO *tso) { unlockClosure((StgClosure*)tso, (const StgInfoTable *)&stg_TSO_info); } #endif /* CMINUSMINUS */ |