From aa84cff4f68e09cc33129ce3fe1bad5aff19e5d9 Mon Sep 17 00:00:00 2001 From: Teo Camarasu Date: Wed, 3 May 2023 13:52:59 +0100 Subject: rts: Ensure non-moving gc is not running when pausing --- rts/RtsAPI.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/rts/RtsAPI.c b/rts/RtsAPI.c index 46cb8a91f8..1d046afbbd 100644 --- a/rts/RtsAPI.c +++ b/rts/RtsAPI.c @@ -19,6 +19,7 @@ #include "StablePtr.h" #include "Threads.h" #include "Weak.h" +#include "sm/NonMoving.h" /* ---------------------------------------------------------------------------- Building Haskell objects from C datatypes. @@ -709,6 +710,16 @@ Capability *pauseTokenCapability(PauseToken *pauseToken) { // See Note [Locking and Pausing the RTS] PauseToken *rts_pause (void) { + + // Wait for any nonmoving collection to finish before pausing the RTS. + // The nonmoving collector needs to synchronise with the mutator, + // so pausing the mutator while a collection is ongoing might lead to deadlock or + // capabilities being prematurely re-awoken. + if (RtsFlags.GcFlags.useNonmoving) { + ACQUIRE_LOCK(&nonmoving_collection_mutex); + } + + // It is an error if this thread already paused the RTS. If another // thread has paused the RTS, then rts_pause will block until rts_resume is // called (and compete with other threads calling rts_pause). The blocking @@ -771,6 +782,10 @@ void rts_resume (PauseToken *pauseToken) releaseAllCapabilities(getNumCapabilities(), NULL, task); exitMyTask(); stgFree(pauseToken); + + if (RtsFlags.GcFlags.useNonmoving) { + RELEASE_LOCK(&nonmoving_collection_mutex); + } } // See RtsAPI.h -- cgit v1.2.1