X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FTask.c;h=94705d5372a6ad804dc21a9b810703b0f153b6cc;hb=53386c359c55bd6eaa13c35fe174c9274ff5888e;hp=bf20e999c314a0147fcc8321863ce4ab7e63c819;hpb=3470e75bd62fa08f86da2607a58c7f0b4aeba9db;p=ghc-hetmet.git diff --git a/ghc/rts/Task.c b/ghc/rts/Task.c index bf20e99..94705d5 100644 --- a/ghc/rts/Task.c +++ b/ghc/rts/Task.c @@ -46,7 +46,6 @@ static nat maxTasks; /* number of tasks currently created */ static nat taskCount; - #if defined(SMP) void startTaskManager( nat maxCount, void (*taskStart)(void) ) @@ -100,6 +99,7 @@ void 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 @@ -120,9 +120,12 @@ stopTaskManager () #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(); @@ -131,11 +134,18 @@ stopTaskManager () return; } +void +resetTaskManagerAfterFork () +{ + barf("resetTaskManagerAfterFork not implemented for SMP"); +} + #else /************ THREADS version *****************/ void -startTaskManager( nat maxCount, void (*taskStart)(void) ) +startTaskManager( nat maxCount, + void (*taskStart)(void) STG_UNUSED ) { /* In the threaded case, maxCount is used to limit the the creation of worker tasks. Tasks are created lazily, i.e., @@ -146,31 +156,28 @@ startTaskManager( nat maxCount, void (*taskStart)(void) ) taskCount = 0; } -void +rtsBool startTask ( void (*taskStart)(void) ) { int r; OSThreadId tid; - /* Locks assumed: rts_mutex */ - /* 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, "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; + return rtsFalse; } @@ -181,14 +188,23 @@ 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; } + + void stopTaskManager () { } + +void +resetTaskManagerAfterFork ( void ) +{ + rts_n_waiting_tasks = 0; + taskCount = 0; +} #endif