From: simonmar Date: Fri, 17 Mar 2000 10:24:44 +0000 (+0000) Subject: [project @ 2000-03-17 10:24:44 by simonmar] X-Git-Tag: Approximately_9120_patches~4959 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=afb300f543ff11b13f07fa620df7ef8b07512c79;p=ghc-hetmet.git [project @ 2000-03-17 10:24:44 by simonmar] Support "interruptible operations": threads which are blocked on MVars, exceptions, I/O, or sleeping are fair game for raiseInThread. --- diff --git a/ghc/rts/Exception.h b/ghc/rts/Exception.h index 07203f9..251a957 100644 --- a/ghc/rts/Exception.h +++ b/ghc/rts/Exception.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: Exception.h,v 1.1 1999/12/01 14:34:38 simonmar Exp $ + * $Id: Exception.h,v 1.2 2000/03/17 10:24:44 simonmar Exp $ * * (c) The GHC Team, 1998-1999 * @@ -9,3 +9,22 @@ extern const StgInfoTable blockAsyncExceptionszh_ret_info; extern const StgInfoTable unblockAsyncExceptionszh_ret_info; + +/* Determine whether a thread is interruptible (ie. blocked + * indefinitely). Interruptible threads can be sent an exception with + * killThread# even if they have async exceptions blocked. + */ +static __inline__ int +interruptible(StgTSO *t) +{ + switch (t->why_blocked) { + case BlockedOnMVar: + case BlockedOnException: + case BlockedOnRead: + case BlockedOnWrite: + case BlockedOnDelay: + return 1; + default: + return 0; + } +} diff --git a/ghc/rts/Exception.hc b/ghc/rts/Exception.hc index 8fc0177..6930071 100644 --- a/ghc/rts/Exception.hc +++ b/ghc/rts/Exception.hc @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: Exception.hc,v 1.8 2000/02/24 17:20:46 simonmar Exp $ + * $Id: Exception.hc,v 1.9 2000/03/17 10:24:44 simonmar Exp $ * * (c) The GHC Team, 1998-1999 * @@ -144,7 +144,6 @@ FN_(blockAsyncExceptionszh_ret_entry) FE_ } - FN_(killThreadzh_fast) { FB_ @@ -158,20 +157,22 @@ FN_(killThreadzh_fast) } /* If the target thread is currently blocking async exceptions, - * we'll have to block until it's ready to accept them. + * we'll have to block until it's ready to accept them. The + * exception is interruptible threads - ie. those that are blocked + * on some resource. */ - if (R1.t->blocked_exceptions != NULL) { - - /* ToDo (SMP): locking if destination thread is currently - * running... - */ - CurrentTSO->link = R1.t->blocked_exceptions; - R1.t->blocked_exceptions = CurrentTSO; - - CurrentTSO->why_blocked = BlockedOnException; - CurrentTSO->block_info.tso = R1.t; + if (R1.t->blocked_exceptions != NULL && !interruptible(R1.t) ) { + + /* ToDo (SMP): locking if destination thread is currently + * running... + */ + CurrentTSO->link = R1.t->blocked_exceptions; + R1.t->blocked_exceptions = CurrentTSO; - BLOCK( R1_PTR | R2_PTR, killThreadzh_fast ); + CurrentTSO->why_blocked = BlockedOnException; + CurrentTSO->block_info.tso = R1.t; + + BLOCK( R1_PTR | R2_PTR, killThreadzh_fast ); } /* Killed threads turn into zombies, which might be garbage