diff options
author | Simon Marlow <marlowsd@gmail.com> | 2018-03-25 14:04:02 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2018-03-25 14:33:27 -0400 |
commit | f7bbc343a624710ecf8f8f5eda620c4f35c90fc8 (patch) | |
tree | 0c409ece9e40aa9e612064ac306d75068ee03b0c /rts/sm/GC.h | |
parent | cf809950efb744ca884e0e0833a80ffd50527ca1 (diff) | |
download | haskell-f7bbc343a624710ecf8f8f5eda620c4f35c90fc8.tar.gz |
Run C finalizers incrementally during mutation
With a large heap it's possible to build up a lot of finalizers
between GCs. We've observed GC spending up to 50% of its time running
finalizers. But there's no reason we have to run finalizers during
GC, and especially no reason we have to block *all* the mutator
threads while *one* GC thread runs finalizers one by one.
I thought about a bunch of alternative ways to handle this, which are
documented along with runSomeFinalizers() in Weak.c. The approach I
settled on is to have a capability run finalizers if it is idle. So
running finalizers is like a low-priority background thread. This
requires some minor scheduler changes, but not much. In the future we
might be able to move more GC work into here (I have my eye on freeing
large blocks, for example).
Test Plan:
* validate
* tested on our system and saw reductions in GC pauses of 40-50%.
Reviewers: bgamari, niteria, osa1, erikd
Reviewed By: bgamari, osa1
Subscribers: rwbarton, thomie, carter
Differential Revision: https://phabricator.haskell.org/D4521
Diffstat (limited to 'rts/sm/GC.h')
-rw-r--r-- | rts/sm/GC.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/rts/sm/GC.h b/rts/sm/GC.h index 7fce87edd4..af662859ff 100644 --- a/rts/sm/GC.h +++ b/rts/sm/GC.h @@ -26,6 +26,8 @@ typedef void (*evac_fn)(void *user, StgClosure **root); StgClosure * isAlive ( StgClosure *p ); void markCAFs ( evac_fn evac, void *user ); +bool doIdleGCWork(Capability *cap, bool all); + extern uint32_t N; extern bool major_gc; |