// needs to acquire all the capabilities). We can't kill
// threads involved in foreign calls.
//
- // * sched_state := SCHED_INTERRUPTED
- //
// * somebody calls shutdownHaskell(), which calls exitScheduler()
//
// * sched_state := SCHED_SHUTTING_DOWN
/* scheduleDoGC() deletes all the threads */
cap = scheduleDoGC(cap,task,rtsFalse,GetRoots);
break;
- case SCHED_INTERRUPTED:
- IF_DEBUG(scheduler, sched_belch("SCHED_INTERRUPTED"));
- break;
case SCHED_SHUTTING_DOWN:
IF_DEBUG(scheduler, sched_belch("SCHED_SHUTTING_DOWN"));
// If we are a worker, just exit. If we're a bound thread
*/
if (sched_state >= SCHED_INTERRUPTING) {
deleteAllThreads(&capabilities[0]);
- sched_state = SCHED_INTERRUPTED;
+ sched_state = SCHED_SHUTTING_DOWN;
}
/* everybody back, start the GC.
// On exit from schedule(), we have a Capability.
releaseCapability(cap);
- taskStop(task);
+ workerTaskStop(task);
}
#endif
#endif
// If we haven't killed all the threads yet, do it now.
- if (sched_state < SCHED_INTERRUPTED) {
+ if (sched_state < SCHED_SHUTTING_DOWN) {
sched_state = SCHED_INTERRUPTING;
scheduleDoGC(NULL,task,rtsFalse,GetRoots);
}
static void
performGC_(rtsBool force_major, void (*get_roots)(evac_fn))
{
- Task *task = myTask();
-
- if (task == NULL) {
- ACQUIRE_LOCK(&sched_mutex);
- task = newBoundTask();
- RELEASE_LOCK(&sched_mutex);
- scheduleDoGC(NULL,task,force_major, get_roots);
- boundTaskExiting(task);
- } else {
- scheduleDoGC(NULL,task,force_major, get_roots);
- }
+ Task *task;
+ // We must grab a new Task here, because the existing Task may be
+ // associated with a particular Capability, and chained onto the
+ // suspended_ccalling_tasks queue.
+ ACQUIRE_LOCK(&sched_mutex);
+ task = newBoundTask();
+ RELEASE_LOCK(&sched_mutex);
+ scheduleDoGC(NULL,task,force_major, get_roots);
+ boundTaskExiting(task);
}
void