summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2017-07-17 16:32:44 (GMT)
committerSimon Marlow <marlowsd@gmail.com>2017-07-18 11:45:47 (GMT)
commit12ae1fa51b2f59e37d6100359b494bee2192ef0a (patch)
treed5c24f6ac1eac5f8252f4dd369a80706b7f86119
parentf656fba19d0cefe05643ddea35d080ea332a6584 (diff)
downloadghc-12ae1fa51b2f59e37d6100359b494bee2192ef0a.zip
ghc-12ae1fa51b2f59e37d6100359b494bee2192ef0a.tar.gz
ghc-12ae1fa51b2f59e37d6100359b494bee2192ef0a.tar.bz2
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
-rw-r--r--rts/Schedule.c19
-rw-r--r--rts/sm/Storage.h22
2 files changed, 14 insertions, 27 deletions
diff --git a/rts/Schedule.c b/rts/Schedule.c
index 7950785..8002ac3 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -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() */
}
diff --git a/rts/sm/Storage.h b/rts/sm/Storage.h
index 2d69eee..aaa4442 100644
--- a/rts/sm/Storage.h
+++ b/rts/sm/Storage.h
@@ -25,17 +25,6 @@ void freeStorage(bool free_heap);
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
-------------------------------------------------------------------------- */
@@ -75,6 +64,17 @@ 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
See [Note allocation accounting] in Storage.c