From 6e2ea06c4a72866396f1b754ec8c2091a9b1e20b Mon Sep 17 00:00:00 2001
From: sof <unknown>
Date: Mon, 18 Feb 2002 13:26:13 +0000
Subject: [PATCH] [project @ 2002-02-18 13:26:12 by sof] 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       |  9 ++++++++-
 ghc/rts/Schedule.c | 13 ++++++++-----
 ghc/rts/Weak.c     |  4 +++-
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/ghc/rts/GC.c b/ghc/rts/GC.c
index 42668e7db512..92a4514ca67f 100644
--- a/ghc/rts/GC.c
+++ b/ghc/rts/GC.c
@@ -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);
 
diff --git a/ghc/rts/Schedule.c b/ghc/rts/Schedule.c
index 01c97fce55b1..1a3843a50874 100644
--- a/ghc/rts/Schedule.c
+++ b/ghc/rts/Schedule.c
@@ -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);
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/ghc/rts/Weak.c b/ghc/rts/Weak.c
index ef26e3b7ba93..5c71710a9ebd 100644
--- a/ghc/rts/Weak.c
+++ b/ghc/rts/Weak.c
@@ -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
-- 
GitLab