diff options
author | Edward Z. Yang <ezyang@mit.edu> | 2013-07-10 13:10:32 -0700 |
---|---|---|
committer | Edward Z. Yang <ezyang@mit.edu> | 2013-07-10 13:10:32 -0700 |
commit | 3a8c50111d5a92594f5c2f1b2b96a7c1cfab82eb (patch) | |
tree | c9a7671c92722c68953a5411c2f49a359923cdf2 /includes/rts/storage | |
parent | 70e20631742e516c6a11c3c112fbd5b4a08c15ac (diff) | |
download | haskell-3a8c50111d5a92594f5c2f1b2b96a7c1cfab82eb.tar.gz |
Add LOCK_CLOSURE macro for use in C--, which inlines the capability check.
This patch also tweaks lockClosure to be INLINE_HEADER, so C-- clients
don't accidentally use them and updates some other code which locks closures
to do the capability check.
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
Diffstat (limited to 'includes/rts/storage')
-rw-r--r-- | includes/rts/storage/SMPClosureOps.h | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/includes/rts/storage/SMPClosureOps.h b/includes/rts/storage/SMPClosureOps.h index 2b058fede8..a8ebb5d0ed 100644 --- a/includes/rts/storage/SMPClosureOps.h +++ b/includes/rts/storage/SMPClosureOps.h @@ -11,13 +11,26 @@ #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; #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); @@ -30,8 +43,10 @@ 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. +// 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; @@ -45,7 +60,7 @@ EXTERN_INLINE StgInfoTable *reallyLockClosure(StgClosure *p) } while (1); } -EXTERN_INLINE StgInfoTable *lockClosure(StgClosure *p) +INLINE_HEADER StgInfoTable *lockClosure(StgClosure *p) { if (n_capabilities == 1) { return (StgInfoTable *)p->header.info; @@ -55,6 +70,8 @@ EXTERN_INLINE StgInfoTable *lockClosure(StgClosure *p) } } +// ToDo: consider splitting tryLockClosure into reallyTryLockClosure, +// same as lockClosure EXTERN_INLINE StgInfoTable *tryLockClosure(StgClosure *p) { StgWord info; @@ -77,7 +94,7 @@ EXTERN_INLINE StgInfoTable * reallyLockClosure(StgClosure *p) { return (StgInfoTable *)p->header.info; } -EXTERN_INLINE StgInfoTable * +INLINE_HEADER StgInfoTable * lockClosure(StgClosure *p) { return (StgInfoTable *)p->header.info; } @@ -95,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 */ |