RE: can you block a thread in GHC by its threadID?

On 22 June 2004 06:11, Bernard James POPE wrote:
Ideally I'd like this function:
blockThread :: ThreadId -> IO ()
and thus:
unBlockThread :: ThreadId -> IO ()
Hmm, might be possible. Can the blocked thread be woken up by an exception? (this is usually the case for blocked threads). Note that if you block a thread and then drop all references to it, the garbage collector will wake up the thread with a BlockedOnDeadMVar exception. I think I'd be tempted to call these functions {stop,continue}Thread to avoid overloading the block/unblock terms any more. Stop/continue is used in Unix land too. To implement this you'll need another StgTSOBlockReason state for stopped threads. Stopping already blocked threads might not be a problem, since (in some cases at least) the blocking operation will be retried when the thread is started again. I'm not sure whether this is always the case though. Stopping a thread blocked on a foreign call cannot be done. Stopping a thread blocked on I/O or delay# will need to remove the thread from the appropriate queue. You'll need two new primops: stopThread#, continueThread#. Take a look at the implementation of killThread# for clues (in ghc/rts/Exception.hc). Don't forget to take into account the case when a thread stops itself (that's the tricky one). Let us know if you need any more guidance... Cheers, Simon

On Tue, Jun 22, 2004 at 09:45:48AM +0100, Simon Marlow wrote:
On 22 June 2004 06:11, Bernard James POPE wrote:
Ideally I'd like this function:
blockThread :: ThreadId -> IO ()
and thus:
unBlockThread :: ThreadId -> IO ()
Hmm, might be possible. Can the blocked thread be woken up by an exception? (this is usually the case for blocked threads).
I guess so.
Note that if you block a thread and then drop all references to it, the garbage collector will wake up the thread with a BlockedOnDeadMVar exception.
That sounds reasonable.
I think I'd be tempted to call these functions {stop,continue}Thread to avoid overloading the block/unblock terms any more. Stop/continue is used in Unix land too.
Yes, those names are fine (I was thinking of suspend/resume).
To implement this you'll need another StgTSOBlockReason state for stopped threads. Stopping already blocked threads might not be a problem, since (in some cases at least) the blocking operation will be retried when the thread is started again. I'm not sure whether this is always the case though. Stopping a thread blocked on a foreign call cannot be done. Stopping a thread blocked on I/O or delay# will need to remove the thread from the appropriate queue.
You'll need two new primops: stopThread#, continueThread#. Take a look at the implementation of killThread# for clues (in ghc/rts/Exception.hc). Don't forget to take into account the case when a thread stops itself (that's the tricky one).
Hmm. In the worst case I can just ban it by comparing the threadIds, and require the use of yield?
Let us know if you need any more guidance...
Thanks. I'll start looking into it in more detail. Supposing that such a thing is indeed possible is there any chance that it could be folded into GHC? (Then I wouldn't have to ship my own variant of the runtime with buddha.) Cheers, Bernie.
participants (2)
-
Bernard James POPE
-
Simon Marlow