summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2008-10-24 10:43:01 +0000
committerSimon Marlow <marlowsd@gmail.com>2008-10-24 10:43:01 +0000
commitb7ea7671c442a0223f34593dc8a1182b15dde0bf (patch)
treef12c8464d0c557baf133a74a36c4b2308b965dac /rts
parent4af25e1a72f2d0f1f523fe5b13c71f1b3dc7a5a5 (diff)
downloadhaskell-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.c19
-rw-r--r--rts/Capability.h4
-rw-r--r--rts/Schedule.c3
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);