summaryrefslogtreecommitdiff
path: root/rts/RtsAPI.c
diff options
context:
space:
mode:
Diffstat (limited to 'rts/RtsAPI.c')
-rw-r--r--rts/RtsAPI.c15
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