diff options
author | Ben Gamari <ben@smart-cactus.org> | 2019-07-31 22:29:13 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2019-10-22 18:57:27 -0400 |
commit | 984745b074c186f6058730087a4fc8156240ec76 (patch) | |
tree | 1025d4e7254ee001346df9cc66aac5f143fb6920 | |
parent | a69b28f4c33cb1909b8560cbc79ff59bf69caf35 (diff) | |
download | haskell-984745b074c186f6058730087a4fc8156240ec76.tar.gz |
nonmoving: Upper-bound time we hold SM_MUTEX for during sweepwip/gc/opt-pause
-rw-r--r-- | rts/sm/NonMovingSweep.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/rts/sm/NonMovingSweep.c b/rts/sm/NonMovingSweep.c index 31a9041880..cf5fcd70d7 100644 --- a/rts/sm/NonMovingSweep.c +++ b/rts/sm/NonMovingSweep.c @@ -293,9 +293,33 @@ void nonmovingSweepMutLists() } } +/* A variant of freeChain_lock that will only hold the lock for at most max_dur + * freed blocks to ensure that we don't starve other lock users (e.g. the + * mutator). + */ +static void freeChain_lock_max(bdescr *bd, int max_dur) +{ + ACQUIRE_SM_LOCK; + bdescr *next_bd; + int i = 0; + while (bd != NULL) { + next_bd = bd->link; + freeGroup(bd); + bd = next_bd; + if (i == max_dur) { + RELEASE_SM_LOCK; + yieldThread(); + ACQUIRE_SM_LOCK; + i = 0; + } + i++; + } + RELEASE_SM_LOCK; +} + void nonmovingSweepLargeObjects() { - freeChain_lock(nonmoving_large_objects); + freeChain_lock_max(nonmoving_large_objects, 10000); nonmoving_large_objects = nonmoving_marked_large_objects; n_nonmoving_large_blocks = n_nonmoving_marked_large_blocks; nonmoving_marked_large_objects = NULL; |