Commit 12ae1fa5 authored by Simon Marlow's avatar Simon Marlow
Browse files

Fix a missing getNewNursery(), and related cleanup

Summary:
When we use nursery chunks with +RTS -n<size>, when the current nursery
runs out we have to check whether there's another chunk available with
getNewNursery().  There was one place we weren't doing this: the ad-hoc
heap check in scheduleProcessInbox().

The impact of the bug was that we would GC too early when using nursery
chunks, especially in programs that used messages (throwTo between
capabilities could do this, also hs_try_putmvar()).

Test Plan: validate, also local testing in our application

Reviewers: bgamari, niteria, austin, erikd

Subscribers: rwbarton, thomie

Differential Revision: https://phabricator.haskell.org/D3749
parent f656fba1
......@@ -993,8 +993,8 @@ scheduleProcessInbox (Capability **pcap USED_IF_THREADS)
Capability *cap = *pcap;
while (!emptyInbox(cap)) {
if (cap->r.rCurrentNursery->link == NULL ||
g0->n_new_large_words >= large_alloc_lim) {
// Executing messages might use heap, so we should check for GC.
if (doYouWantToGC(cap)) {
scheduleDoGC(pcap, cap->running_task, false);
cap = *pcap;
}
......@@ -1183,20 +1183,7 @@ scheduleHandleHeapOverflow( Capability *cap, StgTSO *t )
}
}
// 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 true;
}
// 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);
return false;
}
return true;
return doYouWantToGC(cap);
/* actual GC is done at the end of the while loop in schedule() */
}
......
......@@ -24,17 +24,6 @@ void freeStorage(bool free_heap);
// and initialises other storage-related things.
void storageAddCapabilities (uint32_t from, uint32_t to);
/* -----------------------------------------------------------------------------
Should we GC?
-------------------------------------------------------------------------- */
INLINE_HEADER
bool doYouWantToGC(Capability *cap)
{
return (cap->r.rCurrentNursery->link == NULL ||
g0->n_new_large_words >= large_alloc_lim);
}
/* -----------------------------------------------------------------------------
The storage manager mutex
-------------------------------------------------------------------------- */
......@@ -74,6 +63,17 @@ void resizeNurseriesFixed (void);
StgWord countNurseryBlocks (void);
bool getNewNursery (Capability *cap);
/* -----------------------------------------------------------------------------
Should we GC?
-------------------------------------------------------------------------- */
INLINE_HEADER
bool doYouWantToGC(Capability *cap)
{
return ((cap->r.rCurrentNursery->link == NULL && !getNewNursery(cap)) ||
g0->n_new_large_words >= large_alloc_lim);
}
/* -----------------------------------------------------------------------------
Allocation accounting
......
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