From: simonmar Date: Fri, 18 Jul 2003 14:39:06 +0000 (+0000) Subject: [project @ 2003-07-18 14:39:05 by simonmar] X-Git-Tag: Approx_11550_changesets_converted~679 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=7ede37c94402b0b8586135172e805445052cb298;p=ghc-hetmet.git [project @ 2003-07-18 14:39:05 by simonmar] When doing update-in-place, there is a (small) chance that the thunk may have been blackholed and another thread might be waiting on it. We can't therefore just splat it with the value; we have to check whether it is a blocking queue and awaken any threads that might be waiting on it if so. Should fix the scavenge_mutable_list crash reported recently. If it does, it will be merged to STABLE. --- diff --git a/ghc/compiler/absCSyn/AbsCSyn.lhs b/ghc/compiler/absCSyn/AbsCSyn.lhs index cff7ace..bf9b4ab 100644 --- a/ghc/compiler/absCSyn/AbsCSyn.lhs +++ b/ghc/compiler/absCSyn/AbsCSyn.lhs @@ -1,7 +1,7 @@ % % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % -% $Id: AbsCSyn.lhs,v 1.53 2003/07/02 13:12:33 simonpj Exp $ +% $Id: AbsCSyn.lhs,v 1.54 2003/07/18 14:39:06 simonmar Exp $ % \section[AbstractC]{Abstract C: the last stop before machine code} @@ -251,6 +251,8 @@ data CStmtMacro -- dataToTag# primop -- *only* used in unregisterised builds. -- (see AbsCUtils.dsCOpStmt) | DATA_TO_TAGZH + | AWAKEN_BQ_CLOSURE -- possibly awaken a blocking quuee + -- (used for in-place updates) | REGISTER_FOREIGN_EXPORT -- register a foreign exported fun | REGISTER_IMPORT -- register an imported module diff --git a/ghc/compiler/absCSyn/PprAbsC.lhs b/ghc/compiler/absCSyn/PprAbsC.lhs index 300b5f4..00c8a73 100644 --- a/ghc/compiler/absCSyn/PprAbsC.lhs +++ b/ghc/compiler/absCSyn/PprAbsC.lhs @@ -1306,6 +1306,7 @@ cStmtMacroText UPD_BH_SINGLE_ENTRY = SLIT("UPD_BH_SINGLE_ENTRY") cStmtMacroText PUSH_UPD_FRAME = SLIT("PUSH_UPD_FRAME") cStmtMacroText SET_TAG = SLIT("SET_TAG") cStmtMacroText DATA_TO_TAGZH = SLIT("dataToTagzh") +cStmtMacroText AWAKEN_BQ_CLOSURE = SLIT("AWAKEN_BQ_CLOSURE") cStmtMacroText REGISTER_FOREIGN_EXPORT = SLIT("REGISTER_FOREIGN_EXPORT") cStmtMacroText REGISTER_IMPORT = SLIT("REGISTER_IMPORT") cStmtMacroText REGISTER_DIMPORT = SLIT("REGISTER_DIMPORT") diff --git a/ghc/compiler/codeGen/CgHeapery.lhs b/ghc/compiler/codeGen/CgHeapery.lhs index d68c1e4..7cf05ca 100644 --- a/ghc/compiler/codeGen/CgHeapery.lhs +++ b/ghc/compiler/codeGen/CgHeapery.lhs @@ -1,7 +1,7 @@ % % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % -% $Id: CgHeapery.lhs,v 1.37 2003/07/02 13:12:36 simonpj Exp $ +% $Id: CgHeapery.lhs,v 1.38 2003/07/18 14:39:06 simonmar Exp $ % \section[CgHeapery]{Heap management functions} @@ -372,8 +372,6 @@ allocDynClosure closure_info use_cc blame_cc amodes_with_offsets Occasionally we can update a closure in place instead of allocating new space for it. This is the function that does the business, assuming: - - node points to the closure to be overwritten - - the new closure doesn't contain any pointers if we're using a generational collector. @@ -396,6 +394,12 @@ inPlaceAllocDynClosure closure_info head use_cc amodes_with_offsets in -- GENERATE THE CODE absC ( mkAbstractCs ( - [ CInitHdr closure_info head use_cc 0{-no alloc-} ] + [ + -- don't forget to AWAKEN_BQ_CLOSURE: even though we're + -- doing update-in-place, the thunk might still have been + -- blackholed and another thread might be waiting on it. + CMacroStmt AWAKEN_BQ_CLOSURE [head], + CInitHdr closure_info head use_cc 0{-no alloc-} + ] ++ (map do_move amodes_with_offsets))) \end{code} diff --git a/ghc/includes/Updates.h b/ghc/includes/Updates.h index 952f4d1..0467c07 100644 --- a/ghc/includes/Updates.h +++ b/ghc/includes/Updates.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: Updates.h,v 1.31 2003/04/08 15:32:38 sof Exp $ + * $Id: Updates.h,v 1.32 2003/07/18 14:39:05 simonmar Exp $ * * (c) The GHC Team, 1998-1999 * @@ -133,6 +133,13 @@ Awaken any threads waiting on this computation -------------------------------------------------------------------------- */ +#define AWAKEN_BQ_CLOSURE(closure) \ + { \ + const StgInfoTable *info; \ + info = ((StgClosure *)closure)->header.info; \ + AWAKEN_BQ(info,closure); \ + } + #if defined(PAR) /*