[project @ 2002-02-18 13:26:12 by sof]
authorsof <unknown>
Mon, 18 Feb 2002 13:26:13 +0000 (13:26 +0000)
committersof <unknown>
Mon, 18 Feb 2002 13:26:13 +0000 (13:26 +0000)
Be clear about the lock assumptions of GarbageCollect(); it
is now required to hold sched_mutex.

The real reason for adding this requirement is so that when
prior to scheduling finalizers and doing thread resurrection,
GarbageCollect() may set the lock status of sched_mutex to
the state expected by scheduleFinalizers() and resurrectThreads()
(i.e., unlocked).

Note: this is only an issue with pthreads. In the Win32 threading
model, it's a NOP for a thread to grab a mutex it already holds.

ghc/rts/GC.c
ghc/rts/Schedule.c
ghc/rts/Weak.c

index 42668e7..92a4514 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: GC.c,v 1.129 2001/11/28 15:42:05 simonmar Exp $
+ * $Id: GC.c,v 1.130 2002/02/18 13:26:12 sof Exp $
  *
  * (c) The GHC Team 1998-1999
  *
@@ -218,6 +218,8 @@ pop_mark_stack(void)
       
      - free from-space in each step, and set from-space = to-space.
 
+   Locks held: sched_mutex
+
    -------------------------------------------------------------------------- */
 
 void
@@ -958,12 +960,17 @@ GarbageCollect ( void (*get_roots)(evac_fn), rtsBool force_major_gc )
   // Reset the nursery
   resetNurseries();
 
+  // let go of lock (so that it can be re-grabbed below).
+  RELEASE_LOCK(&sched_mutex);
+  
   // start any pending finalizers 
   scheduleFinalizers(old_weak_ptr_list);
   
   // send exceptions to any threads which were about to die 
   resurrectThreads(resurrected_threads);
 
+  ACQUIRE_LOCK(&sched_mutex);
+
   // Update the stable pointer hash table.
   updateStablePtrTable(major_gc);
 
index 01c97fc..1a3843a 100644 (file)
@@ -1,5 +1,5 @@
 /* ---------------------------------------------------------------------------
- * $Id: Schedule.c,v 1.130 2002/02/16 00:30:05 sof Exp $
+ * $Id: Schedule.c,v 1.131 2002/02/18 13:26:13 sof Exp $
  *
  * (c) The GHC Team, 1998-2000
  *
@@ -595,9 +595,7 @@ schedule( void )
        /* and SMP mode ..? */
        releaseCapability(cap);
 #endif
-       RELEASE_LOCK(&sched_mutex);
        GarbageCollect(GetRoots,rtsTrue);
-       ACQUIRE_LOCK(&sched_mutex);
        if (   EMPTY_QUEUE(blocked_queue_hd)
            && EMPTY_RUN_QUEUE()
            && EMPTY_QUEUE(sleeping_queue) ) {
@@ -1344,9 +1342,7 @@ schedule( void )
 #if defined(RTS_SUPPORTS_THREADS)
       IF_DEBUG(scheduler,sched_belch("doing GC"));
 #endif
-      RELEASE_LOCK(&sched_mutex);
       GarbageCollect(GetRoots,rtsFalse);
-      ACQUIRE_LOCK(&sched_mutex);
       ready_to_gc = rtsFalse;
 #ifdef SMP
       broadcastCondition(&gc_pending_cond);
@@ -2320,13 +2316,18 @@ void (*extra_roots)(evac_fn);
 void
 performGC(void)
 {
+  /* Obligated to hold this lock upon entry */
+  ACQUIRE_LOCK(&sched_mutex);
   GarbageCollect(GetRoots,rtsFalse);
+  RELEASE_LOCK(&sched_mutex);
 }
 
 void
 performMajorGC(void)
 {
+  ACQUIRE_LOCK(&sched_mutex);
   GarbageCollect(GetRoots,rtsTrue);
+  RELEASE_LOCK(&sched_mutex);
 }
 
 static void
@@ -2339,8 +2340,10 @@ AllRoots(evac_fn evac)
 void
 performGCWithRoots(void (*get_roots)(evac_fn))
 {
+  ACQUIRE_LOCK(&sched_mutex);
   extra_roots = get_roots;
   GarbageCollect(AllRoots,rtsFalse);
+  RELEASE_LOCK(&sched_mutex);
 }
 
 /* -----------------------------------------------------------------------------
index ef26e3b..5c71710 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Weak.c,v 1.20 2001/11/26 16:54:22 simonmar Exp $
+ * $Id: Weak.c,v 1.21 2002/02/18 13:26:13 sof Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -56,6 +56,8 @@ finalizeWeakPointersNow(void)
  * The weak pointer object itself may not be alive - i.e. we may be
  * looking at either an object in from-space or one in to-space.  It
  * doesn't really matter either way.
+ *
+ * Pre-condition: sched_mutex _not_ held.
  */
 
 void