Commit 75fd5dc2 authored by Simon Marlow's avatar Simon Marlow

Don't get a new nursery if we exceeded large_alloc_lim

Summary:
When using nursery chunks, if we failed a heap check due to
large_alloc_lim, we would pointlessly keep grabbing new nursery
chunks when we should just GC immediately.

Test Plan: validate

Reviewers: austin, bgamari, niteria

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D1072
parent a592e9ff
......@@ -1084,6 +1084,17 @@ schedulePostRunThread (Capability *cap, StgTSO *t)
static rtsBool
scheduleHandleHeapOverflow( Capability *cap, StgTSO *t )
{
if (cap->r.rHpLim == NULL || cap->context_switch) {
// Sometimes we miss a context switch, e.g. when calling
// primitives in a tight loop, MAYBE_GC() doesn't check the
// context switch flag, and we end up waiting for a GC.
// See #1984, and concurrent/should_run/1984
cap->context_switch = 0;
appendToRunQueue(cap,t);
} else {
pushOnRunQueue(cap,t);
}
// did the task ask for a large block?
if (cap->r.rHpAlloc > BLOCK_SIZE) {
// if so, get one and push it on the front of the nursery.
......@@ -1141,27 +1152,23 @@ scheduleHandleHeapOverflow( Capability *cap, StgTSO *t )
// run queue before us and steal the large block, but in that
// case the thread will just end up requesting another large
// block.
pushOnRunQueue(cap,t);
return rtsFalse; /* not actually GC'ing */
}
}
// if we got here because we exceeded large_alloc_lim, then
// proceed straight to GC.
if (g0->n_new_large_words >= large_alloc_lim) {
return rtsTrue;
}
// Otherwise, we just ran out of space in the current nursery.
// Grab another nursery if we can.
if (getNewNursery(cap)) {
debugTrace(DEBUG_sched, "thread %ld got a new nursery", t->id);
pushOnRunQueue(cap,t);
return rtsFalse;
}
if (cap->r.rHpLim == NULL || cap->context_switch) {
// Sometimes we miss a context switch, e.g. when calling
// primitives in a tight loop, MAYBE_GC() doesn't check the
// context switch flag, and we end up waiting for a GC.
// See #1984, and concurrent/should_run/1984
cap->context_switch = 0;
appendToRunQueue(cap,t);
} else {
pushOnRunQueue(cap,t);
}
return rtsTrue;
/* actual GC is done at the end of the while loop in schedule() */
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment