diff options
author | Simon Marlow <marlowsd@gmail.com> | 2008-10-24 10:43:01 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2008-10-24 10:43:01 +0000 |
commit | b7ea7671c442a0223f34593dc8a1182b15dde0bf (patch) | |
tree | f12c8464d0c557baf133a74a36c4b2308b965dac /rts | |
parent | 4af25e1a72f2d0f1f523fe5b13c71f1b3dc7a5a5 (diff) | |
download | haskell-b7ea7671c442a0223f34593dc8a1182b15dde0bf.tar.gz |
Move the freeing of Capabilities later in the shutdown sequence
Fixes a bug whereby the Capability has been freed but other
Capabilities are still trying to steal sparks from its pool.
Diffstat (limited to 'rts')
-rw-r--r-- | rts/Capability.c | 19 | ||||
-rw-r--r-- | rts/Capability.h | 4 | ||||
-rw-r--r-- | rts/Schedule.c | 3 |
3 files changed, 19 insertions, 7 deletions
diff --git a/rts/Capability.c b/rts/Capability.c index 92396e9ef0..c8103117c9 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -767,7 +767,6 @@ shutdownCapability (Capability *cap, Task *task, rtsBool safe) } debugTrace(DEBUG_sched, "capability %d is stopped.", cap->no); - freeCapability(cap); RELEASE_LOCK(&cap->lock); break; } @@ -805,14 +804,28 @@ tryGrabCapability (Capability *cap, Task *task) #endif /* THREADED_RTS */ -void -freeCapability (Capability *cap) { +static void +freeCapability (Capability *cap) +{ stgFree(cap->mut_lists); #if defined(THREADED_RTS) || defined(PARALLEL_HASKELL) freeSparkPool(cap->sparks); #endif } +void +freeCapabilities (void) +{ +#if defined(THREADED_RTS) + nat i; + for (i=0; i < n_capabilities; i++) { + freeCapability(&capabilities[i]); + } +#else + freeCapability(&MainCapability); +#endif +} + /* --------------------------------------------------------------------------- Mark everything directly reachable from the Capabilities. When using multiple GC threads, each GC thread marks all Capabilities diff --git a/rts/Capability.h b/rts/Capability.h index dc0a28ea57..9446a7e779 100644 --- a/rts/Capability.h +++ b/rts/Capability.h @@ -262,8 +262,8 @@ extern void grabCapability (Capability **pCap); // cause all capabilities to context switch as soon as possible. void setContextSwitches(void); -// Free a capability on exit -void freeCapability (Capability *cap); +// Free all capabilities +void freeCapabilities (void); // FOr the GC: void markSomeCapabilities (evac_fn evac, void *user, nat i0, nat delta, diff --git a/rts/Schedule.c b/rts/Schedule.c index cc5cbb476f..8ab964dcb3 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -2114,14 +2114,13 @@ exitScheduler( boundTaskExiting(task); stopTaskManager(); } -#else - freeCapability(&MainCapability); #endif } void freeScheduler( void ) { + freeCapabilities(); freeTaskManager(); if (n_capabilities != 1) { stgFree(capabilities); |