diff options
Diffstat (limited to 'rts/Schedule.c')
-rw-r--r-- | rts/Schedule.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/rts/Schedule.c b/rts/Schedule.c index 41d0dba953..12b192c3d5 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -165,7 +165,9 @@ static bool scheduleHandleThreadFinished( Capability *cap, Task *task, StgTSO *t ); static bool scheduleNeedHeapProfile(bool ready_to_gc); static void scheduleDoGC( Capability **pcap, Task *task, - bool force_major, bool deadlock_detect ); + bool force_major, + bool deadlock_detect, + bool force_nonconcurrent ); static void deleteThread (StgTSO *tso); static void deleteAllThreads (void); @@ -264,7 +266,7 @@ schedule (Capability *initialCapability, Task *task) case SCHED_INTERRUPTING: debugTrace(DEBUG_sched, "SCHED_INTERRUPTING"); /* scheduleDoGC() deletes all the threads */ - scheduleDoGC(&cap,task,true,false); + scheduleDoGC(&cap, task, true, false, false); // after scheduleDoGC(), we must be shutting down. Either some // other Capability did the final GC, or we did it above, @@ -573,7 +575,7 @@ run_thread: } if (ready_to_gc || scheduleNeedHeapProfile(ready_to_gc)) { - scheduleDoGC(&cap,task,false,false); + scheduleDoGC(&cap, task, false, false, false); } } /* end of while() */ } @@ -937,7 +939,10 @@ scheduleDetectDeadlock (Capability **pcap, Task *task) // they are unreachable and will therefore be sent an // exception. Any threads thus released will be immediately // runnable. - scheduleDoGC (pcap, task, true/*force major GC*/, true/*deadlock detection*/); + scheduleDoGC (pcap, task, + true/*force major GC*/, + true/*deadlock detection*/, + false/*force_nonconcurrent*/); cap = *pcap; // when force_major == true. scheduleDoGC sets // recent_activity to ACTIVITY_DONE_GC and turns off the timer @@ -1562,7 +1567,7 @@ void releaseAllCapabilities(uint32_t n, Capability *keep_cap, Task *task) // behind deadlock_detect argument. static void scheduleDoGC (Capability **pcap, Task *task USED_IF_THREADS, - bool force_major, bool deadlock_detect) + bool force_major, bool deadlock_detect, bool force_nonconcurrent) { Capability *cap = *pcap; bool heap_census; @@ -1855,9 +1860,11 @@ delete_threads_and_gc: // emerge they don't immediately re-enter the GC. pending_sync = 0; signalCondition(&sync_finished_cond); - GarbageCollect(collect_gen, heap_census, deadlock_detect, gc_type, cap, idle_cap); + GarbageCollect(collect_gen, heap_census, deadlock_detect, + force_nonconcurrent, gc_type, cap, idle_cap); #else - GarbageCollect(collect_gen, heap_census, deadlock_detect, 0, cap, NULL); + GarbageCollect(collect_gen, heap_census, deadlock_detect, + force_nonconcurrent, 0, cap, NULL); #endif // If we're shutting down, don't leave any idle GC work to do. @@ -2734,7 +2741,7 @@ exitScheduler (bool wait_foreign USED_IF_THREADS) nonmovingStop(); Capability *cap = task->cap; waitForCapability(&cap,task); - scheduleDoGC(&cap,task,true,false); + scheduleDoGC(&cap,task,true,false,false); ASSERT(task->incall->tso == NULL); releaseCapability(cap); } @@ -2789,7 +2796,7 @@ void markScheduler (evac_fn evac USED_IF_NOT_THREADS, -------------------------------------------------------------------------- */ static void -performGC_(bool force_major) +performGC_(bool force_major, bool force_nonconcurrent) { Task *task; Capability *cap = NULL; @@ -2802,7 +2809,7 @@ performGC_(bool force_major) // TODO: do we need to traceTask*() here? waitForCapability(&cap,task); - scheduleDoGC(&cap,task,force_major,false); + scheduleDoGC(&cap, task, force_major, false, force_nonconcurrent); releaseCapability(cap); boundTaskExiting(task); } @@ -2810,13 +2817,19 @@ performGC_(bool force_major) void performGC(void) { - performGC_(false); + performGC_(false, false); } void performMajorGC(void) { - performGC_(true); + performGC_(true, false); +} + +void +performBlockingMajorGC(void) +{ + performGC_(true, true); } /* --------------------------------------------------------------------------- |