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
/* ---------------------------------------------------------------------------
/* ---------------------------------------------------------------------------
- * $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
*
*
* (c) The GHC Team, 1998-2003
*
// just because the last one hasn't yet reached the
// "waiting for capability" state
startingWorkerThread = rtsTrue;
// just because the last one hasn't yet reached the
// "waiting for capability" state
startingWorkerThread = rtsTrue;
+ if(!startTask(taskStart))
+ {
+ startingWorkerThread = rtsFalse;
+ }
startTask ( void (*taskStart)(void) )
{
int r;
startTask ( void (*taskStart)(void) )
{
int r;
rts_n_waiting_tasks););
// the task will run as soon as a capability is available,
// so there's no need to wake it.
rts_n_waiting_tasks););
// the task will run as soon as a capability is available,
// so there's no need to wake it.
}
/* 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));
}
/* 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));
taskCount++;
IF_DEBUG(scheduler,fprintf(stderr,"scheduler: startTask: new task %ld (total_count: %d; waiting: %d)\n", tid, taskCount, rts_n_waiting_tasks););
taskCount++;
IF_DEBUG(scheduler,fprintf(stderr,"scheduler: startTask: new task %ld (total_count: %d; waiting: %d)\n", tid, taskCount, rts_n_waiting_tasks););
extern void stopTaskManager ( void );
extern void resetTaskManagerAfterFork ( 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__ */
#endif /* RTS_SUPPORTS_THREADS */
#endif /* __TASK_H__ */