diff options
author | Tobias Guggenmos <tguggenm@redhat.com> | 2019-09-08 14:45:08 +0200 |
---|---|---|
committer | Tobias Guggenmos <tguggenm@redhat.com> | 2019-09-08 22:34:29 +0200 |
commit | 718e7011e08deffa915629f6f2f07767817d5813 (patch) | |
tree | 5804062e9be8fb0619c59bf56b7b3c1b99ef06a3 /rts/RtsAPI.c | |
parent | 6ad6303b9fa6190c495fc43fbbb4243b63d4383a (diff) | |
download | haskell-wip/ghc-debug-sched.tar.gz |
Add api to pause single threaded RTSwip/ghc-debug-sched
Improve Implementation of pausing the single threaded RTS
Stop abusing mutexes
Diffstat (limited to 'rts/RtsAPI.c')
-rw-r--r-- | rts/RtsAPI.c | 48 |
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); } |