summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2019-07-31 22:29:13 -0400
committerBen Gamari <ben@smart-cactus.org>2019-10-22 18:57:27 -0400
commit984745b074c186f6058730087a4fc8156240ec76 (patch)
tree1025d4e7254ee001346df9cc66aac5f143fb6920 /rts
parenta69b28f4c33cb1909b8560cbc79ff59bf69caf35 (diff)
downloadhaskell-984745b074c186f6058730087a4fc8156240ec76.tar.gz
nonmoving: Upper-bound time we hold SM_MUTEX for during sweepwip/gc/opt-pause
Diffstat (limited to 'rts')
-rw-r--r--rts/sm/NonMovingSweep.c26
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;