[project @ 2002-09-17 12:11:44 by simonmar]
authorsimonmar <unknown>
Tue, 17 Sep 2002 12:11:45 +0000 (12:11 +0000)
committersimonmar <unknown>
Tue, 17 Sep 2002 12:11:45 +0000 (12:11 +0000)
The GC wasn't properly marking pending signal handlers, which could
lead to "EVACUATED object entered!" errors.  Also, a race occurs if a
signal arrives during GC.  Two fixes:

  (a) mark all pending signal handlers during GC, and
  (b) block signals during GC

MERGE TO STABLE

ghc/rts/GC.c
ghc/rts/Signals.c
ghc/rts/Signals.h

index 6b8bd3d..40fea7d 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: GC.c,v 1.141 2002/09/10 10:43:52 simonmar Exp $
+ * $Id: GC.c,v 1.142 2002/09/17 12:11:44 simonmar Exp $
  *
  * (c) The GHC Team 1998-1999
  *
@@ -27,6 +27,7 @@
 #include "Prelude.h"
 #include "ParTicky.h"          // ToDo: move into Rts.h
 #include "GCCompact.h"
+#include "Signals.h"
 #if defined(GRAN) || defined(PAR)
 # include "GranSimRts.h"
 # include "ParallelRts.h"
@@ -249,6 +250,9 @@ GarbageCollect ( void (*get_roots)(evac_fn), rtsBool force_major_gc )
                     Now, Now));
 #endif
 
+  // block signals
+  blockUserSignals();
+
   // tell the stats department that we've started a GC 
   stat_startGC();
 
@@ -1030,6 +1034,9 @@ GarbageCollect ( void (*get_roots)(evac_fn), rtsBool force_major_gc )
   // ok, GC over: tell the stats department what happened. 
   stat_endGC(allocated, collected, live, copied, N);
 
+  // unblock signals again
+  unblockUserSignals();
+
   //PAR_TICKY_TP();
 }
 
index d2a61e3..68a9d5c 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Signals.c,v 1.28 2002/09/06 14:34:13 simonmar Exp $
+ * $Id: Signals.c,v 1.29 2002/09/17 12:11:45 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -286,6 +286,27 @@ startSignalHandlers(void)
   unblockUserSignals();
 }
 
+/* ----------------------------------------------------------------------------
+ * Mark signal handlers during GC.
+ *
+ * We do this rather than trying to start all the signal handlers
+ * prior to GC, because that requires extra heap for the new threads.
+ * Signals must be blocked (see blockUserSignals() above) during GC to
+ * avoid race conditions.
+ * -------------------------------------------------------------------------- */
+
+void
+markSignalHandlers (evac_fn evac)
+{
+    StgPtr *p;
+
+    p = next_pending_handler;
+    while (p != pending_handler_buf) {
+       p--;
+       evac((StgClosure **)p);
+    }
+}
+
 #else // PAR
 StgInt 
 stg_sig_install(StgInt sig, StgInt spi, StgStablePtr handler, sigset_t *mask)
index 4ea7523..d00c8b6 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Signals.h,v 1.7 2002/03/12 13:57:14 simonmar Exp $
+ * $Id: Signals.h,v 1.8 2002/09/17 12:11:45 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -24,6 +24,7 @@ extern void    awaitUserSignals(void);
 /* sig_install declared in PrimOps.h */
 
 extern void startSignalHandlers(void);
+extern void markSignalHandlers (evac_fn evac);
 extern void initDefaultHandlers(void);
 
 #else