diff options
-rw-r--r-- | rts/RtsAPI.c | 15 |
1 files changed, 15 insertions, 0 deletions
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 |