Commit 68b76e0e authored by Duncan Coutts's avatar Duncan Coutts
Browse files

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.
parent cb2d37da
...@@ -676,6 +676,31 @@ prodCapability (Capability *cap, Task *task) ...@@ -676,6 +676,31 @@ prodCapability (Capability *cap, Task *task)
RELEASE_LOCK(&cap->lock); RELEASE_LOCK(&cap->lock);
} }
/* ----------------------------------------------------------------------------
* 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 * shutdownCapability
* *
...@@ -692,8 +717,9 @@ prodCapability (Capability *cap, Task *task) ...@@ -692,8 +717,9 @@ prodCapability (Capability *cap, Task *task)
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
void 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; nat i;
task->cap = cap; task->cap = cap;
...@@ -785,33 +811,20 @@ shutdownCapability (Capability *cap, Task *task, rtsBool safe) ...@@ -785,33 +811,20 @@ shutdownCapability (Capability *cap, Task *task, rtsBool safe)
// threads performing foreign calls that will eventually try to // threads performing foreign calls that will eventually try to
// return via resumeThread() and attempt to grab cap->lock. // return via resumeThread() and attempt to grab cap->lock.
// closeMutex(&cap->lock); // closeMutex(&cap->lock);
#endif /* THREADED_RTS */
} }
/* ---------------------------------------------------------------------------- void
* tryGrabCapability shutdownCapabilities(Task *task, rtsBool safe)
*
* Attempt to gain control of a Capability if it is free.
*
* ------------------------------------------------------------------------- */
rtsBool
tryGrabCapability (Capability *cap, Task *task)
{ {
if (cap->running_task != NULL) return rtsFalse; nat i;
ACQUIRE_LOCK(&cap->lock); for (i=0; i < n_capabilities; i++) {
if (cap->running_task != NULL) { ASSERT(task->incall->tso == NULL);
RELEASE_LOCK(&cap->lock); shutdownCapability(&capabilities[i], task, safe);
return rtsFalse;
} }
task->cap = cap;
cap->running_task = task;
RELEASE_LOCK(&cap->lock);
return rtsTrue;
} }
#endif /* THREADED_RTS */
static void static void
freeCapability (Capability *cap) freeCapability (Capability *cap)
{ {
......
...@@ -240,11 +240,6 @@ void prodCapability (Capability *cap, Task *task); ...@@ -240,11 +240,6 @@ void prodCapability (Capability *cap, Task *task);
// //
void prodAllCapabilities (void); 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. // Attempt to gain control of a Capability if it is free.
// //
rtsBool tryGrabCapability (Capability *cap, Task *task); rtsBool tryGrabCapability (Capability *cap, Task *task);
...@@ -270,6 +265,15 @@ extern void grabCapability (Capability **pCap); ...@@ -270,6 +265,15 @@ extern void grabCapability (Capability **pCap);
#endif /* !THREADED_RTS */ #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. // cause all capabilities to context switch as soon as possible.
void setContextSwitches(void); void setContextSwitches(void);
INLINE_HEADER void contextSwitchCapability(Capability *cap); INLINE_HEADER void contextSwitchCapability(Capability *cap);
......
...@@ -2030,16 +2030,7 @@ exitScheduler (rtsBool wait_foreign USED_IF_THREADS) ...@@ -2030,16 +2030,7 @@ exitScheduler (rtsBool wait_foreign USED_IF_THREADS)
} }
sched_state = SCHED_SHUTTING_DOWN; sched_state = SCHED_SHUTTING_DOWN;
#if defined(THREADED_RTS) shutdownCapabilities(task, wait_foreign);
{
nat i;
for (i = 0; i < n_capabilities; i++) {
ASSERT(task->incall->tso == NULL);
shutdownCapability(&capabilities[i], task, wait_foreign);
}
}
#endif
boundTaskExiting(task); boundTaskExiting(task);
} }
......
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