[project @ 2003-07-18 14:39:05 by simonmar]
authorsimonmar <unknown>
Fri, 18 Jul 2003 14:39:06 +0000 (14:39 +0000)
committersimonmar <unknown>
Fri, 18 Jul 2003 14:39:06 +0000 (14:39 +0000)
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.

ghc/compiler/absCSyn/AbsCSyn.lhs
ghc/compiler/absCSyn/PprAbsC.lhs
ghc/compiler/codeGen/CgHeapery.lhs
ghc/includes/Updates.h

index cff7ace..bf9b4ab 100644 (file)
@@ -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
index 300b5f4..00c8a73 100644 (file)
@@ -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")
index d68c1e4..7cf05ca 100644 (file)
@@ -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}
index 952f4d1..0467c07 100644 (file)
@@ -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
  *
    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) 
 
 /*