summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Coutts <duncan@well-typed.com>2011-05-26 15:08:43 +0100
committerDuncan Coutts <duncan@well-typed.com>2011-05-26 18:47:38 +0100
commit68b76e0e49d4d95e1bfe9343697e2abc99470791 (patch)
treeee7ad40c51594063d45e2dddc0ac3c9655d9fc72
parentcb2d37da5792b13f5988049f67a24263b4de4ff2 (diff)
downloadhaskell-68b76e0e49d4d95e1bfe9343697e2abc99470791.tar.gz
Rearrange shutdownCapability code slightly
This is mostly for the beneift of having sensible places to put tracing code later. We want a code path that has somewhere to trace (in order): (1) starting up all capabilities; (2) N * starting up an individual capability; (3) N * shutting down an individual capability; (4) shutting down all capabilities. This has to work in both threaded and non-threaded modes. Locations (1) and (2) are provided by initCapabilities and initCapability respectively. Previously, there was no loccation for (4) and while shutdownCapability should be usable for (3) it was only called in the !THREADED_RTS case. Now, shutdownCapability is called unconditionally (and the body is conditonal on THREADED_RTS) and there is a new shutdownCapabilities that calls shutdownCapability in a loop.
-rw-r--r--rts/Capability.c57
-rw-r--r--rts/Capability.h14
-rw-r--r--rts/Schedule.c11
3 files changed, 45 insertions, 37 deletions
diff --git a/rts/Capability.c b/rts/Capability.c
index 9091fdde0c..3e1dd972c7 100644
--- a/rts/Capability.c
+++ b/rts/Capability.c
@@ -677,6 +677,31 @@ prodCapability (Capability *cap, Task *task)
}
/* ----------------------------------------------------------------------------
+ * tryGrabCapability
+ *
+ * Attempt to gain control of a Capability if it is free.
+ *
+ * ------------------------------------------------------------------------- */
+
+rtsBool
+tryGrabCapability (Capability *cap, Task *task)
+{
+ if (cap->running_task != NULL) return rtsFalse;
+ ACQUIRE_LOCK(&cap->lock);
+ if (cap->running_task != NULL) {
+ RELEASE_LOCK(&cap->lock);
+ return rtsFalse;
+ }
+ task->cap = cap;
+ cap->running_task = task;
+ RELEASE_LOCK(&cap->lock);
+ return rtsTrue;
+}
+
+
+#endif /* THREADED_RTS */
+
+/* ----------------------------------------------------------------------------
* shutdownCapability
*
* At shutdown time, we want to let everything exit as cleanly as
@@ -692,8 +717,9 @@ prodCapability (Capability *cap, Task *task)
* ------------------------------------------------------------------------- */
void
-shutdownCapability (Capability *cap, Task *task, rtsBool safe)
+shutdownCapability (Capability *cap USED_IF_THREADS, Task *task USED_IF_THREADS, rtsBool safe USED_IF_THREADS)
{
+#if defined(THREADED_RTS)
nat i;
task->cap = cap;
@@ -785,33 +811,20 @@ shutdownCapability (Capability *cap, Task *task, rtsBool safe)
// threads performing foreign calls that will eventually try to
// return via resumeThread() and attempt to grab cap->lock.
// closeMutex(&cap->lock);
+
+#endif /* THREADED_RTS */
}
-/* ----------------------------------------------------------------------------
- * tryGrabCapability
- *
- * Attempt to gain control of a Capability if it is free.
- *
- * ------------------------------------------------------------------------- */
-
-rtsBool
-tryGrabCapability (Capability *cap, Task *task)
+void
+shutdownCapabilities(Task *task, rtsBool safe)
{
- if (cap->running_task != NULL) return rtsFalse;
- ACQUIRE_LOCK(&cap->lock);
- if (cap->running_task != NULL) {
- RELEASE_LOCK(&cap->lock);
- return rtsFalse;
+ nat i;
+ for (i=0; i < n_capabilities; i++) {
+ ASSERT(task->incall->tso == NULL);
+ shutdownCapability(&capabilities[i], task, safe);
}
- task->cap = cap;
- cap->running_task = task;
- RELEASE_LOCK(&cap->lock);
- return rtsTrue;
}
-
-#endif /* THREADED_RTS */
-
static void
freeCapability (Capability *cap)
{
diff --git a/rts/Capability.h b/rts/Capability.h
index d580a8383d..d380af9cff 100644
--- a/rts/Capability.h
+++ b/rts/Capability.h
@@ -240,11 +240,6 @@ void prodCapability (Capability *cap, Task *task);
//
void prodAllCapabilities (void);
-// Waits for a capability to drain of runnable threads and workers,
-// and then acquires it. Used at shutdown time.
-//
-void shutdownCapability (Capability *cap, Task *task, rtsBool wait_foreign);
-
// Attempt to gain control of a Capability if it is free.
//
rtsBool tryGrabCapability (Capability *cap, Task *task);
@@ -270,6 +265,15 @@ extern void grabCapability (Capability **pCap);
#endif /* !THREADED_RTS */
+// Waits for a capability to drain of runnable threads and workers,
+// and then acquires it. Used at shutdown time.
+//
+void shutdownCapability (Capability *cap, Task *task, rtsBool wait_foreign);
+
+// Shut down all capabilities.
+//
+void shutdownCapabilities(Task *task, rtsBool wait_foreign);
+
// cause all capabilities to context switch as soon as possible.
void setContextSwitches(void);
INLINE_HEADER void contextSwitchCapability(Capability *cap);
diff --git a/rts/Schedule.c b/rts/Schedule.c
index 9636223836..fd5536b913 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -2030,16 +2030,7 @@ exitScheduler (rtsBool wait_foreign USED_IF_THREADS)
}
sched_state = SCHED_SHUTTING_DOWN;
-#if defined(THREADED_RTS)
- {
- nat i;
-
- for (i = 0; i < n_capabilities; i++) {
- ASSERT(task->incall->tso == NULL);
- shutdownCapability(&capabilities[i], task, wait_foreign);
- }
- }
-#endif
+ shutdownCapabilities(task, wait_foreign);
boundTaskExiting(task);
}