diff options
author | Simon Marlow <marlowsd@gmail.com> | 2009-05-18 10:41:08 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2009-05-18 10:41:08 +0000 |
commit | 8de62de730e07c23468ec8facd25aca557ad7c11 (patch) | |
tree | ea9a0ea1b0fea0835ccad917caf1cfd2c044287a | |
parent | 8a3ed3364fbc74b1f1b87b049737da2b251f92df (diff) | |
download | haskell-8de62de730e07c23468ec8facd25aca557ad7c11.tar.gz |
Fix #3236: emit a helpful error message when the RTS has not been initialised
-rw-r--r-- | rts/RtsAPI.c | 6 | ||||
-rw-r--r-- | rts/Schedule.c | 4 | ||||
-rw-r--r-- | rts/Task.c | 23 |
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(¤tTaskKey); #endif @@ -94,6 +93,8 @@ freeTaskManager (void) freeThreadLocalKey(¤tTaskKey); #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; } |