summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rts/RtsAPI.c6
-rw-r--r--rts/Schedule.c4
-rw-r--r--rts/Task.c23
3 files changed, 18 insertions, 15 deletions
diff --git a/rts/RtsAPI.c b/rts/RtsAPI.c
index 911e703b75..d0d8d58a34 100644
--- a/rts/RtsAPI.c
+++ b/rts/RtsAPI.c
@@ -664,13 +664,7 @@ rts_lock (void)
Capability *cap;
Task *task;
- // ToDo: get rid of this lock in the common case. We could store
- // a free Task in thread-local storage, for example. That would
- // leave just one lock on the path into the RTS: cap->lock when
- // acquiring the Capability.
- ACQUIRE_LOCK(&sched_mutex);
task = newBoundTask();
- RELEASE_LOCK(&sched_mutex);
cap = NULL;
waitForReturnCapability(&cap, task);
diff --git a/rts/Schedule.c b/rts/Schedule.c
index 97923022b4..0b4c5b6284 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -2235,9 +2235,7 @@ exitScheduler(
{
Task *task = NULL;
- ACQUIRE_LOCK(&sched_mutex);
task = newBoundTask();
- RELEASE_LOCK(&sched_mutex);
// If we haven't killed all the threads yet, do it now.
if (sched_state < SCHED_SHUTTING_DOWN) {
@@ -2301,9 +2299,7 @@ performGC_(rtsBool force_major)
// We must grab a new Task here, because the existing Task may be
// associated with a particular Capability, and chained onto the
// suspended_ccalling_tasks queue.
- ACQUIRE_LOCK(&sched_mutex);
task = newBoundTask();
- RELEASE_LOCK(&sched_mutex);
waitForReturnCapability(&task->cap,task);
scheduleDoGC(task->cap,task,force_major);
diff --git a/rts/Task.c b/rts/Task.c
index 9397789105..af94a8aabe 100644
--- a/rts/Task.c
+++ b/rts/Task.c
@@ -31,6 +31,7 @@ static Task *task_free_list = NULL; // singly-linked
static nat taskCount;
static nat tasksRunning;
static nat workerCount;
+static int tasksInitialized = 0;
/* -----------------------------------------------------------------------------
* Remembering the current thread's Task
@@ -51,13 +52,11 @@ Task *my_task;
void
initTaskManager (void)
{
- static int initialized = 0;
-
- if (!initialized) {
+ if (!tasksInitialized) {
taskCount = 0;
workerCount = 0;
tasksRunning = 0;
- initialized = 1;
+ tasksInitialized = 1;
#if defined(THREADED_RTS)
newThreadLocalKey(&currentTaskKey);
#endif
@@ -94,6 +93,8 @@ freeTaskManager (void)
freeThreadLocalKey(&currentTaskKey);
#endif
+ tasksInitialized = 0;
+
return tasksRunning;
}
@@ -150,7 +151,17 @@ newBoundTask (void)
{
Task *task;
- ASSERT_LOCK_HELD(&sched_mutex);
+ if (!tasksInitialized) {
+ errorBelch("newBoundTask: RTS is not initialised; call hs_init() first");
+ stg_exit(EXIT_FAILURE);
+ }
+
+ // ToDo: get rid of this lock in the common case. We could store
+ // a free Task in thread-local storage, for example. That would
+ // leave just one lock on the path into the RTS: cap->lock when
+ // acquiring the Capability.
+ ACQUIRE_LOCK(&sched_mutex);
+
if (task_free_list == NULL) {
task = newTask();
} else {
@@ -169,6 +180,8 @@ newBoundTask (void)
taskEnter(task);
+ RELEASE_LOCK(&sched_mutex);
+
debugTrace(DEBUG_sched, "new task (taskCount: %d)", taskCount);
return task;
}