[commit: ghc] master: Don't get a new nursery if we exceeded large_alloc_lim (75fd5dc)
git at git.haskell.org
git at git.haskell.org
Wed Jul 15 13:58:47 UTC 2015
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/75fd5dc204fb6bb9014f6bba4d680facbc952faf/ghc
>---------------------------------------------------------------
commit 75fd5dc204fb6bb9014f6bba4d680facbc952faf
Author: Simon Marlow <marlowsd at gmail.com>
Date: Wed Jul 15 13:07:35 2015 +0100
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
>---------------------------------------------------------------
75fd5dc204fb6bb9014f6bba4d680facbc952faf
rts/Schedule.c | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/rts/Schedule.c b/rts/Schedule.c
index f1e95bf..257e39a 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -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() */
}
More information about the ghc-commits
mailing list