[project @ 2004-05-06 12:20:04 by wolfgang]
authorwolfgang <unknown>
Thu, 6 May 2004 12:20:06 +0000 (12:20 +0000)
committerwolfgang <unknown>
Thu, 6 May 2004 12:20:06 +0000 (12:20 +0000)
Threaded RTS: Fix a deadlock situation

The flag startingWorkerThread that is used by startSchedulerTaskIfNecessary
(in Schedule.c) has to be reset if startTask (in Task.c) decides not to
start another task after all (if a task is already waiting).
When the flag isn't reset, this leads to a deadlock the next time a new
worker thread is actually needed.

MERGE TO STABLE

ghc/rts/Schedule.c
ghc/rts/Task.c
ghc/rts/Task.h

index 6296990..e20eae2 100644 (file)
@@ -1,5 +1,5 @@
 /* ---------------------------------------------------------------------------
- * $Id: Schedule.c,v 1.195 2004/04/13 13:43:11 simonmar Exp $
+ * $Id: Schedule.c,v 1.196 2004/05/06 12:20:04 wolfgang Exp $
  *
  * (c) The GHC Team, 1998-2003
  *
@@ -276,7 +276,10 @@ startSchedulerTaskIfNecessary(void)
       // just because the last one hasn't yet reached the
       // "waiting for capability" state
       startingWorkerThread = rtsTrue;
-      startTask(taskStart);
+      if(!startTask(taskStart))
+      {
+        startingWorkerThread = rtsFalse;
+      }
     }
   }
 }
index 6579abc..94705d5 100644 (file)
@@ -156,7 +156,7 @@ startTaskManager( nat maxCount,
   taskCount = 0;
 }
 
-void
+rtsBool
 startTask ( void (*taskStart)(void) )
 {
   int r;
@@ -171,13 +171,13 @@ startTask ( void (*taskStart)(void) )
                               rts_n_waiting_tasks););
     // the task will run as soon as a capability is available,
     // so there's no need to wake it.
-    return;
+    return rtsFalse;
   }
 
   /* If the task limit has been reached, just return. */
   if (maxTasks > 0 && taskCount == maxTasks) {
     IF_DEBUG(scheduler,fprintf(stderr,"scheduler: startTask: task limit (%d) reached, not creating new one.\n",maxTasks));
-    return;
+    return rtsFalse;
   }
   
 
@@ -188,7 +188,7 @@ startTask ( void (*taskStart)(void) )
   taskCount++;
 
   IF_DEBUG(scheduler,fprintf(stderr,"scheduler: startTask: new task %ld (total_count: %d; waiting: %d)\n", tid, taskCount, rts_n_waiting_tasks););
-  return;
+  return rtsTrue;
 }
 
 
index fcea419..b5a4dd2 100644 (file)
@@ -30,7 +30,7 @@ extern void startTaskManager ( nat maxTasks, void (*taskStart)(void) );
 extern void stopTaskManager ( void );
 extern void resetTaskManagerAfterFork ( void );
 
-extern void startTask ( void (*taskStart)(void) );
+extern rtsBool startTask ( void (*taskStart)(void) );
 
 #endif /* RTS_SUPPORTS_THREADS */
 #endif /* __TASK_H__ */