/* number of tasks currently created */
static nat taskCount;
-
#if defined(SMP)
void
startTaskManager( nat maxCount, void (*taskStart)(void) )
taskTable[taskCount].gc_etime = 0.0;
taskTable[taskCount].elapsedtimestart = stat_getElapsedTime();
- IF_DEBUG(scheduler,fprintf(stderr,"scheduler: Started task: %ld\n",tid););
+ IF_DEBUG(scheduler,debugBelch("scheduler: Started task: %ld\n",tid););
return;
}
stopTaskManager ()
{
nat i;
+ OSThreadId tid = osThreadId();
/* Don't want to use pthread_cancel, since we'd have to install
* these silly exception handlers (pthread_cleanup_{push,pop}) around
/* Wait for all the tasks to terminate */
for (i = 0; i < maxCount; i++) {
- IF_DEBUG(scheduler,fprintf(stderr,"scheduler: waiting for task %ld\n",
+ IF_DEBUG(scheduler,debugBelch("scheduler: waiting for task %ld\n",
taskTable[i].id));
pthread_join(taskTable[i].id, NULL);
}
#endif
/* Send 'em all a SIGHUP. That should shut 'em up. */
- await_death = maxCount;
+ await_death = maxCount - 1;
for (i = 0; i < maxCount; i++) {
- pthread_kill(taskTable[i].id,SIGTERM);
+ /* don't cancel the thread running this piece of code. */
+ if ( taskTable[i].id != tid ) {
+ pthread_kill(taskTable[i].id,SIGTERM);
+ }
}
while (await_death > 0) {
sched_yield();
return;
}
+void
+resetTaskManagerAfterFork ()
+{
+ barf("resetTaskManagerAfterFork not implemented for SMP");
+}
+
#else
/************ THREADS version *****************/
taskCount = 0;
}
-void
+rtsBool
startTask ( void (*taskStart)(void) )
{
int r;
OSThreadId tid;
/* If more than one worker thread is known to be blocked waiting
- on thread_ready_cond, signal it rather than creating a new one.
+ on thread_ready_cond, don't create a new one.
*/
if ( rts_n_waiting_tasks > 0) {
- IF_DEBUG(scheduler,fprintf(stderr,
+ IF_DEBUG(scheduler,debugBelch(
"scheduler: startTask: %d tasks waiting, not creating new one.\n",
rts_n_waiting_tasks););
- signalCondition(&thread_ready_cond);
- /* Not needed, but gives more 'interesting' thread schedules when testing */
- yieldThread();
- return;
+ // the task will run as soon as a capability is available,
+ // so there's no need to wake it.
+ 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;
+ IF_DEBUG(scheduler,debugBelch("scheduler: startTask: task limit (%d) reached, not creating new one.\n",maxTasks));
+ return rtsFalse;
}
}
taskCount++;
- IF_DEBUG(scheduler,fprintf(stderr,"scheduler: startTask: new task %ld (total_count: %d; waiting: %d)\n", tid, taskCount, rts_n_waiting_tasks););
- return;
+ IF_DEBUG(scheduler,debugBelch("scheduler: startTask: new task %ld (total_count: %d; waiting: %d)\n", tid, taskCount, rts_n_waiting_tasks););
+ return rtsTrue;
}
+
+
void
stopTaskManager ()
{
}
+
+void
+resetTaskManagerAfterFork ( void )
+{
+ rts_n_waiting_tasks = 0;
+ taskCount = 0;
+}
#endif