From 8de62de730e07c23468ec8facd25aca557ad7c11 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Mon, 18 May 2009 10:41:08 +0000 Subject: [PATCH] Fix #3236: emit a helpful error message when the RTS has not been initialised --- rts/RtsAPI.c | 6 ------ rts/Schedule.c | 4 ---- rts/Task.c | 23 ++++++++++++++++++----- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/rts/RtsAPI.c b/rts/RtsAPI.c index 911e703..d0d8d58 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 9792302..0b4c5b6 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 9397789..af94a8a 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; } -- 1.7.10.4