Fix #3236: emit a helpful error message when the RTS has not been initialised
authorSimon Marlow <marlowsd@gmail.com>
Mon, 18 May 2009 10:41:08 +0000 (10:41 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Mon, 18 May 2009 10:41:08 +0000 (10:41 +0000)
rts/RtsAPI.c
rts/Schedule.c
rts/Task.c

index 911e703..d0d8d58 100644 (file)
@@ -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);
index 9792302..0b4c5b6 100644 (file)
@@ -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);
index 9397789..af94a8a 100644 (file)
@@ -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;
 }