[project @ 2005-03-02 10:00:36 by simonmar]
[ghc-hetmet.git] / ghc / rts / Task.c
index 4086127..ad05208 100644 (file)
@@ -46,7 +46,6 @@ static nat maxTasks;
 /* number of tasks currently created */
 static nat taskCount; 
 
-
 #if defined(SMP)
 void
 startTaskManager( nat maxCount, void (*taskStart)(void) )
@@ -92,7 +91,7 @@ startTask ( void (*taskStart)(void) )
   taskTable[taskCount].gc_etime = 0.0;
   taskTable[taskCount].elapsedtimestart = stat_getElapsedTime();
 
-  IF_DEBUG(scheduler,fprintf(stderr,"scheduler: Started task: %ld\n",tid););
+  IF_DEBUG(scheduler,debugBelch("scheduler: Started task: %ld\n",tid););
   return;
 }
 
@@ -100,6 +99,7 @@ void
 stopTaskManager ()
 {
   nat i;
+  OSThreadId tid = osThreadId();
 
   /* Don't want to use pthread_cancel, since we'd have to install
    * these silly exception handlers (pthread_cleanup_{push,pop}) around
@@ -113,16 +113,19 @@ stopTaskManager ()
   
   /* Wait for all the tasks to terminate */
   for (i = 0; i < maxCount; i++) {
-    IF_DEBUG(scheduler,fprintf(stderr,"scheduler: waiting for task %ld\n", 
+    IF_DEBUG(scheduler,debugBelch("scheduler: waiting for task %ld\n", 
                               taskTable[i].id));
     pthread_join(taskTable[i].id, NULL);
   }
 #endif
 
   /* Send 'em all a SIGHUP.  That should shut 'em up. */
-  await_death = maxCount;
+  await_death = maxCount - 1;
   for (i = 0; i < maxCount; i++) {
-    pthread_kill(taskTable[i].id,SIGTERM);
+    /* don't cancel the thread running this piece of code. */
+    if ( taskTable[i].id != tid ) {
+      pthread_kill(taskTable[i].id,SIGTERM);
+    }
   }
   while (await_death > 0) {
     sched_yield();
@@ -131,6 +134,12 @@ stopTaskManager ()
   return;
 }
 
+void
+resetTaskManagerAfterFork ()
+{
+       barf("resetTaskManagerAfterFork not implemented for SMP");
+}
+
 #else
 /************ THREADS version *****************/
 
@@ -147,29 +156,28 @@ startTaskManager( nat maxCount,
   taskCount = 0;
 }
 
-void
+rtsBool
 startTask ( void (*taskStart)(void) )
 {
   int r;
   OSThreadId tid;
   
   /* If more than one worker thread is known to be blocked waiting
-     on thread_ready_cond, signal it rather than creating a new one.
+     on thread_ready_cond, don't create a new one.
   */
   if ( rts_n_waiting_tasks > 0) {
-    IF_DEBUG(scheduler,fprintf(stderr,
+    IF_DEBUG(scheduler,debugBelch(
                               "scheduler: startTask: %d tasks waiting, not creating new one.\n", 
                               rts_n_waiting_tasks););
-    signalCondition(&thread_ready_cond);
-    /* Not needed, but gives more 'interesting' thread schedules when testing */
-    yieldThread();
-    return;
+    // the task will run as soon as a capability is available,
+    // so there's no need to wake it.
+    return rtsFalse;
   }
 
   /* If the task limit has been reached, just return. */
   if (maxTasks > 0 && taskCount == maxTasks) {
-    IF_DEBUG(scheduler,fprintf(stderr,"scheduler: startTask: task limit (%d) reached, not creating new one.\n",maxTasks));
-    return;
+    IF_DEBUG(scheduler,debugBelch("scheduler: startTask: task limit (%d) reached, not creating new one.\n",maxTasks));
+    return rtsFalse;
   }
   
 
@@ -179,15 +187,24 @@ startTask ( void (*taskStart)(void) )
   }
   taskCount++;
 
-  IF_DEBUG(scheduler,fprintf(stderr,"scheduler: startTask: new task %ld (total_count: %d; waiting: %d)\n", tid, taskCount, rts_n_waiting_tasks););
-  return;
+  IF_DEBUG(scheduler,debugBelch("scheduler: startTask: new task %ld (total_count: %d; waiting: %d)\n", tid, taskCount, rts_n_waiting_tasks););
+  return rtsTrue;
 }
 
+
+
 void
 stopTaskManager ()
 {
 
 }
+
+void
+resetTaskManagerAfterFork ( void )
+{
+       rts_n_waiting_tasks = 0;
+       taskCount = 0;
+}
 #endif