summaryrefslogtreecommitdiff
path: root/rts/RtsAPI.c
diff options
context:
space:
mode:
Diffstat (limited to 'rts/RtsAPI.c')
-rw-r--r--rts/RtsAPI.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/rts/RtsAPI.c b/rts/RtsAPI.c
index 5cb7d29f27..7fd1ddadeb 100644
--- a/rts/RtsAPI.c
+++ b/rts/RtsAPI.c
@@ -19,6 +19,7 @@
#include "Threads.h"
#include "Weak.h"
#include "StableName.h"
+#include "assert.h"
/* ----------------------------------------------------------------------------
Building Haskell objects from C datatypes.
@@ -651,20 +652,18 @@ static bool rts_paused = false;
// Halt execution of all Haskell threads.
// It is different to rts_lock because it pauses all capabilities. rts_lock
// only pauses a single capability.
-RtsPaused rts_pause (void)
+void rts_pause (RtsPaused * paused)
{
- struct RtsPaused_ paused;
- paused.pausing_task = newBoundTask();
- stopAllCapabilities(&paused.capabilities, paused.pausing_task);
+ paused->pausing_task = newBoundTask();
+ stopAllCapabilities(&paused->capabilities, paused->pausing_task);
rts_paused = true;
- return paused;
}
-void rts_unpause (RtsPaused paused)
+void rts_unpause (RtsPaused * paused)
{
rts_paused = false;
- releaseAllCapabilities(n_capabilities, paused.capabilities, paused.pausing_task);
- freeTask(paused.pausing_task);
+ releaseAllCapabilities(n_capabilities, paused->capabilities, paused->pausing_task);
+ freeTask(paused->pausing_task);
}
@@ -702,17 +701,36 @@ void rts_listMiscRoots (ListRootsCb cb, void *user)
threadStablePtrTable(&list_roots_helper, (void *)&ctx);
}
-#else
-RtsPaused rts_pause (void)
+#else // !DEFINED(THREADED_RTS)
+void rts_pause (RtsPaused * paused STG_UNUSED)
{
- struct RtsPaused_ paused;
- paused.pausing_task = NULL;
- paused.capabilities = NULL;
- return paused;
+ ACQUIRE_LOCK(&nonThreadedPause.pauseLock);
+
+ // Wait until all previous pausers have unpaused the rts
+ while(nonThreadedPause.state != RUNNING){
+ waitCondition(&nonThreadedPause.stateChange, &nonThreadedPause.pauseLock);
+ }
+
+ ++nonThreadedPause.pauseRequests;
+ nonThreadedPause.state = PAUSING;
+
+ // Wait for rts to actually pause
+ while(nonThreadedPause.state != PAUSED){
+ waitCondition(&nonThreadedPause.stateChange, &nonThreadedPause.pauseLock);
+ }
+
+ RELEASE_LOCK(&nonThreadedPause.pauseLock);
}
-void rts_unpause (RtsPaused paused STG_UNUSED)
+void rts_unpause (RtsPaused * paused STG_UNUSED)
{
+ ACQUIRE_LOCK(&NonTreadedPause.pauseLock);
+ assert(nonThreadedPause.state == PAUSED);
+ --nonThreadedPause.pauseRequests;
+ if (!nonThreadedPause.pauseRequests){
+ nonThreadedPause.state = STARTING;
+ }
+ RELEASE_LOCK(&nonThreadedPause.pauseRequestMutex);
}