summaryrefslogtreecommitdiff
path: root/rts/PrimOps.cmm
diff options
context:
space:
mode:
authorPatrick Palka <patrick@parcs.ath.cx>2013-08-21 15:25:18 -0400
committerPatrick Palka <patrick@parcs.ath.cx>2013-08-26 22:21:16 -0400
commit036910ad0d01cfd23fa53930fca2dd880faa6536 (patch)
tree069d6bff28cde8dd1b09835972e299966f16fd3d /rts/PrimOps.cmm
parent776cfe28cf089c24a56a288f2f0c49494f7d9e47 (diff)
downloadhaskell-036910ad0d01cfd23fa53930fca2dd880faa6536.tar.gz
UniqSupply: make mkSplitUniqSupply thread-safe
unsafeInterleaveIO is used instead of unsafeDupableInterleaveIO because a mk_supply thunk that is simultaneously entered by two threads should evaluate to the same UniqSupply. The UniqSupply counter is now incremented atomically using the RTS's atomic_inc(). To mitigate the extra overhead of unsafeInterleaveIO in the single-threaded compiler, noDuplicate# is changed to exit early when n_capabilities == 1.
Diffstat (limited to 'rts/PrimOps.cmm')
-rw-r--r--rts/PrimOps.cmm5
1 files changed, 5 insertions, 0 deletions
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index ced15eec99..d8acaef77b 100644
--- a/rts/PrimOps.cmm
+++ b/rts/PrimOps.cmm
@@ -2008,6 +2008,11 @@ INFO_TABLE_RET(stg_noDuplicate, RET_SMALL, W_ info_ptr)
stg_noDuplicatezh /* no arg list: explicit stack layout */
{
+ // With a single capability there's no chance of work duplication.
+ if (CInt[n_capabilities] == 1 :: CInt) {
+ jump %ENTRY_CODE(Sp(0)) [];
+ }
+
STK_CHK(WDS(1), stg_noDuplicatezh);
// leave noDuplicate frame in case the current