Commit b7ea7671 authored by Simon Marlow's avatar Simon Marlow
Browse files

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.
parent 4af25e1a
...@@ -767,7 +767,6 @@ shutdownCapability (Capability *cap, Task *task, rtsBool safe) ...@@ -767,7 +767,6 @@ shutdownCapability (Capability *cap, Task *task, rtsBool safe)
} }
debugTrace(DEBUG_sched, "capability %d is stopped.", cap->no); debugTrace(DEBUG_sched, "capability %d is stopped.", cap->no);
freeCapability(cap);
RELEASE_LOCK(&cap->lock); RELEASE_LOCK(&cap->lock);
break; break;
} }
...@@ -805,14 +804,28 @@ tryGrabCapability (Capability *cap, Task *task) ...@@ -805,14 +804,28 @@ tryGrabCapability (Capability *cap, Task *task)
#endif /* THREADED_RTS */ #endif /* THREADED_RTS */
void static void
freeCapability (Capability *cap) { freeCapability (Capability *cap)
{
stgFree(cap->mut_lists); stgFree(cap->mut_lists);
#if defined(THREADED_RTS) || defined(PARALLEL_HASKELL) #if defined(THREADED_RTS) || defined(PARALLEL_HASKELL)
freeSparkPool(cap->sparks); freeSparkPool(cap->sparks);
#endif #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 Mark everything directly reachable from the Capabilities. When
using multiple GC threads, each GC thread marks all Capabilities using multiple GC threads, each GC thread marks all Capabilities
......
...@@ -262,8 +262,8 @@ extern void grabCapability (Capability **pCap); ...@@ -262,8 +262,8 @@ extern void grabCapability (Capability **pCap);
// cause all capabilities to context switch as soon as possible. // cause all capabilities to context switch as soon as possible.
void setContextSwitches(void); void setContextSwitches(void);
// Free a capability on exit // Free all capabilities
void freeCapability (Capability *cap); void freeCapabilities (void);
// FOr the GC: // FOr the GC:
void markSomeCapabilities (evac_fn evac, void *user, nat i0, nat delta, void markSomeCapabilities (evac_fn evac, void *user, nat i0, nat delta,
......
...@@ -2114,14 +2114,13 @@ exitScheduler( ...@@ -2114,14 +2114,13 @@ exitScheduler(
boundTaskExiting(task); boundTaskExiting(task);
stopTaskManager(); stopTaskManager();
} }
#else
freeCapability(&MainCapability);
#endif #endif
} }
void void
freeScheduler( void ) freeScheduler( void )
{ {
freeCapabilities();
freeTaskManager(); freeTaskManager();
if (n_capabilities != 1) { if (n_capabilities != 1) {
stgFree(capabilities); stgFree(capabilities);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment