[project @ 2005-09-16 09:37:18 by simonmar]
authorsimonmar <unknown>
Fri, 16 Sep 2005 09:37:18 +0000 (09:37 +0000)
committersimonmar <unknown>
Fri, 16 Sep 2005 09:37:18 +0000 (09:37 +0000)
rev. 1.258 introduced a double acquire of sched_mutex; createThread()
is called with sched_mutex already held by rts_evalIO() and friends.
This fixes it.

ghc/rts/PrimOps.cmm
ghc/rts/Schedule.c
ghc/rts/Schedule.h

index abd71fe..25f8245 100644 (file)
@@ -874,10 +874,14 @@ forkzh_fast
   
   MAYBE_GC(R1_PTR, forkzh_fast);
 
+  foreign "C" ACQUIRE_LOCK(sched_mutex "ptr");
+
   // create it right now, return ThreadID in R1
   "ptr" R1 = foreign "C" createIOThread( RtsFlags_GcFlags_initialStkSize(RtsFlags), 
                                   R1 "ptr");
-  foreign "C" scheduleThread(R1 "ptr");
+  foreign "C" scheduleThreadLocked(R1 "ptr");
+
+  foreign "C" RELEASE_LOCK(sched_mutex "ptr");
 
   // switch at the earliest opportunity
   CInt[context_switch] = 1 :: CInt;
index a496c3d..49c28e6 100644 (file)
@@ -2311,12 +2311,9 @@ StgTSO *
 createThread(nat size)
 #endif
 {
-
     StgTSO *tso;
     nat stack_size;
 
-    ACQUIRE_LOCK(&sched_mutex);
-
     /* First check whether we should create a thread at all */
 #if defined(PARALLEL_HASKELL)
   /* check that no more than RtsFlags.ParFlags.maxThreads threads are created */
@@ -2324,7 +2321,6 @@ createThread(nat size)
     threadsIgnored++;
     debugBelch("{createThread}Daq ghuH: refusing to create another thread; no more than %d threads allowed (currently %d)\n",
          RtsFlags.ParFlags.maxThreads, advisory_thread_count);
-    RELEASE_LOCK(&sched_mutex);
     return END_TSO_QUEUE;
   }
   threadsCreated++;
@@ -2475,7 +2471,6 @@ createThread(nat size)
   IF_DEBUG(scheduler,sched_belch("created thread %ld, stack size = %lx words", 
                                 (long)tso->id, (long)tso->stack_size));
 #endif    
-  RELEASE_LOCK(&sched_mutex);
   return tso;
 }
 
@@ -2546,8 +2541,8 @@ activateSpark (rtsSpark spark)
  * on this thread's stack before the scheduler is invoked.
  * ------------------------------------------------------------------------ */
 
-static void
-scheduleThread_(StgTSO *tso)
+void
+scheduleThreadLocked(StgTSO *tso)
 {
   // The thread goes at the *end* of the run-queue, to avoid possible
   // starvation of any threads already on the queue.
@@ -2559,7 +2554,7 @@ void
 scheduleThread(StgTSO* tso)
 {
   ACQUIRE_LOCK(&sched_mutex);
-  scheduleThread_(tso);
+  scheduleThreadLocked(tso);
   RELEASE_LOCK(&sched_mutex);
 }
 
index c4560ed..f4ba398 100644 (file)
@@ -36,6 +36,9 @@ void awakenBlockedQueue (StgTSO *tso);
 void awakenBlockedQueueNoLock (StgTSO *tso);
 #endif
 
+/* Version of scheduleThread that doesn't take sched_mutex */
+void scheduleThreadLocked(StgTSO *tso);
+
 /* unblockOne()
  *
  * Takes a pointer to the beginning of a blocked TSO queue, and