[project @ 1999-11-11 17:19:15 by simonmar]
authorsimonmar <unknown>
Thu, 11 Nov 1999 17:19:15 +0000 (17:19 +0000)
committersimonmar <unknown>
Thu, 11 Nov 1999 17:19:15 +0000 (17:19 +0000)
Re-instate interrupted stuff.  If the scheduler finds the interrupted
flag to be set, it calls deleteThread() on all the runnable and
blocked threads, wakes up any main thread clients that were waiting,
and then either

(a) returns, in the UP case
(b) waits for more work, in the SMP case.

ghc/rts/Schedule.c

index 1c55585..c35d098 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Schedule.c,v 1.31 1999/11/09 15:46:54 simonmar Exp $
+ * $Id: Schedule.c,v 1.32 1999/11/11 17:19:15 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -188,6 +188,68 @@ schedule( void )
 
   while (1) {
 
+    /* If we're interrupted (the user pressed ^C, or some other
+     * termination condition occurred), kill all the currently running
+     * threads.
+     */
+    if (interrupted) {
+      IF_DEBUG(scheduler,belch("schedule: interrupted"));
+      for (t = run_queue_hd; t != END_TSO_QUEUE; t = t->link) {
+       deleteThread(t);
+      }
+      for (t = blocked_queue_hd; t != END_TSO_QUEUE; t = t->link) {
+       deleteThread(t);
+      }
+      run_queue_hd = run_queue_tl = END_TSO_QUEUE;
+      blocked_queue_hd = blocked_queue_tl = END_TSO_QUEUE;
+    }
+
+    /* Go through the list of main threads and wake up any
+     * clients whose computations have finished.  ToDo: this
+     * should be done more efficiently without a linear scan
+     * of the main threads list, somehow...
+     */
+#ifdef SMP
+    { 
+      StgMainThread *m, **prev;
+      prev = &main_threads;
+      for (m = main_threads; m != NULL; m = m->link) {
+       if (m->tso->whatNext == ThreadComplete) {
+         if (m->ret) {
+           *(m->ret) = (StgClosure *)m->tso->sp[0];
+         }
+         *prev = m->link;
+         m->stat = Success;
+         pthread_cond_broadcast(&m->wakeup);
+       }
+       if (m->tso->whatNext == ThreadKilled) {
+         *prev = m->link;
+         m->stat = Killed;
+         pthread_cond_broadcast(&m->wakeup);
+       }
+      }
+    }
+#else
+    /* If our main thread has finished or been killed, return.
+     */
+    {
+      StgMainThread *m = main_threads;
+      if (m->tso->whatNext == ThreadComplete
+         || m->tso->whatNext == ThreadKilled) {
+       main_threads = main_threads->link;
+       if (m->tso->whatNext == ThreadComplete) {
+         /* we finished successfully, fill in the return value */
+         if (m->ret) { *(m->ret) = (StgClosure *)m->tso->sp[0]; };
+         m->stat = Success;
+         return;
+       } else {
+         m->stat = Killed;
+         return;
+       }
+      }
+    }
+#endif
+
     /* Check whether any waiting threads need to be woken up.  If the
      * run queue is empty, and there are no other tasks running, we
      * can wait indefinitely for something to happen.
@@ -449,56 +511,6 @@ schedule( void )
       pthread_cond_broadcast(&gc_pending_cond);
 #endif
     }
-    
-    /* Go through the list of main threads and wake up any
-     * clients whose computations have finished.  ToDo: this
-     * should be done more efficiently without a linear scan
-     * of the main threads list, somehow...
-     */
-#ifdef SMP
-    { 
-      StgMainThread *m, **prev;
-      prev = &main_threads;
-      for (m = main_threads; m != NULL; m = m->link) {
-       if (m->tso->whatNext == ThreadComplete) {
-         if (m->ret) {
-           *(m->ret) = (StgClosure *)m->tso->sp[0];
-         }
-         *prev = m->link;
-         m->stat = Success;
-         pthread_cond_broadcast(&m->wakeup);
-       }
-       if (m->tso->whatNext == ThreadKilled) {
-         *prev = m->link;
-         m->stat = Killed;
-         pthread_cond_broadcast(&m->wakeup);
-       }
-      }
-    }
-#else
-    /* If our main thread has finished or been killed, return.
-     * If we were re-entered as a result of a _ccall_gc, then
-     * pop the blocked thread off the ccalling_threads stack back
-     * into CurrentTSO.
-     */
-    {
-      StgMainThread *m = main_threads;
-      if (m->tso->whatNext == ThreadComplete
-         || m->tso->whatNext == ThreadKilled) {
-       main_threads = main_threads->link;
-       if (m->tso->whatNext == ThreadComplete) {
-         /* we finished successfully, fill in the return value */
-         if (m->ret) { *(m->ret) = (StgClosure *)m->tso->sp[0]; };
-         m->stat = Success;
-         return;
-       } else {
-         m->stat = Killed;
-         return;
-       }
-      }
-    }
-#endif
-
   } /* end of while(1) */
 }