[commit: ghc] ghc-parmake-gsoc: UniqSupply: make mkSplitUniqSupply thread-safe (036910a)
git at git.haskell.org
git at git.haskell.org
Tue Aug 27 16:11:34 CEST 2013
Repository : ssh://git@git.haskell.org/ghc
On branch : ghc-parmake-gsoc
Link : http://ghc.haskell.org/trac/ghc/changeset/036910ad0d01cfd23fa53930fca2dd880faa6536/ghc
>---------------------------------------------------------------
commit 036910ad0d01cfd23fa53930fca2dd880faa6536
Author: Patrick Palka <patrick at parcs.ath.cx>
Date: Wed Aug 21 15:25:18 2013 -0400
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.
>---------------------------------------------------------------
036910ad0d01cfd23fa53930fca2dd880faa6536
compiler/basicTypes/UniqSupply.lhs | 5 +++--
compiler/cbits/genSym.c | 6 +++++-
compiler/ghc.mk | 6 ++++++
rts/PrimOps.cmm | 5 +++++
4 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/compiler/basicTypes/UniqSupply.lhs b/compiler/basicTypes/UniqSupply.lhs
index 0c6007a..fea1489 100644
--- a/compiler/basicTypes/UniqSupply.lhs
+++ b/compiler/basicTypes/UniqSupply.lhs
@@ -29,7 +29,7 @@ module UniqSupply (
import Unique
import FastTypes
-import GHC.IO (unsafeDupableInterleaveIO)
+import GHC.IO
import MonadUtils
import Control.Monad
@@ -80,7 +80,8 @@ mkSplitUniqSupply c
-- This is one of the most hammered bits in the whole compiler
mk_supply
- = unsafeDupableInterleaveIO (
+ -- NB: Use unsafeInterleaveIO for thread-safety.
+ = unsafeInterleaveIO (
genSym >>= \ u_ -> case iUnbox u_ of { u -> (
mk_supply >>= \ s1 ->
mk_supply >>= \ s2 ->
diff --git a/compiler/cbits/genSym.c b/compiler/cbits/genSym.c
index 2d9779b..8614e97 100644
--- a/compiler/cbits/genSym.c
+++ b/compiler/cbits/genSym.c
@@ -4,6 +4,10 @@
static HsInt GenSymCounter = 0;
HsInt genSym(void) {
- return GenSymCounter++;
+ if (n_capabilities == 1) {
+ return GenSymCounter++;
+ } else {
+ return atomic_inc((StgWord *)&GenSymCounter);
+ }
}
diff --git a/compiler/ghc.mk b/compiler/ghc.mk
index 2a7a8c4..af289d4 100644
--- a/compiler/ghc.mk
+++ b/compiler/ghc.mk
@@ -309,6 +309,12 @@ compiler_stage1_CONFIGURE_OPTS += --flags=stage1
compiler_stage2_CONFIGURE_OPTS += --flags=stage2
compiler_stage3_CONFIGURE_OPTS += --flags=stage3
+ifeq "$(GhcThreaded)" "YES"
+# We pass THREADED_RTS to the stage2 C files so that cbits/genSym.c will bring
+# the threaded version of atomic_inc() into scope.
+compiler_stage2_CONFIGURE_OPTS += --ghc-option=-optc-DTHREADED_RTS
+endif
+
ifeq "$(GhcWithNativeCodeGen)" "YES"
compiler_stage1_CONFIGURE_OPTS += --flags=ncg
compiler_stage2_CONFIGURE_OPTS += --flags=ncg
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index ced15ee..d8acaef 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
More information about the ghc-commits
mailing list