From: simonmar Date: Thu, 11 Nov 1999 17:19:15 +0000 (+0000) Subject: [project @ 1999-11-11 17:19:15 by simonmar] X-Git-Tag: Approximately_9120_patches~5573 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=bc9cfb591dbfbfd607e8558877645a836dd62f99;p=ghc-hetmet.git [project @ 1999-11-11 17:19:15 by simonmar] 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. --- diff --git a/ghc/rts/Schedule.c b/ghc/rts/Schedule.c index 1c55585..c35d098 100644 --- a/ghc/rts/Schedule.c +++ b/ghc/rts/Schedule.c @@ -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) */ }