Marcin 'Qrczak' Kowalczyk
qrczak at knm.org.pl
Thu Apr 6 19:36:12 EDT 2006
"Simon Marlow" <simonmar at microsoft.com> writes:
> I think it's unnecessary to treat signals in the way you do - you're
> assuming that a signal interrupts the current thread and runs a new
> computation (the signal handler) on the same stack, completely blocking
> the interrupted thread until the signal handler completes. This is the
> wrong way to view signal handlers, IMO: they should run in completely
> separate threads (perhaps a higher priority thread, if possible).
This can be emulated in my model: by designating a thread for system
signals, possibly even letting it spawn a new thread for each signal.
Most Unix signals are supposed to abort the process however, and thus
a mechanism for aborting one thread from another is needed anyway.
I think async exceptions are not that much easier than
Async signals include the ability to pause threads in safe points,
which is needed for SIGSTOP / SIGTSTP and for my fork() wrapper. This
is not archievable with signals spawning threads + async exceptions.
> + you don't have to block signals just because you happen to
> be holding a mutex. Synchronisation with a signal handler
> is just synchronisation with another thread.
It's still very probable that taking a mutex coincides with the need
to block async exceptions: an async exception in the middle of a
critical section implies a danger of leaving data in an inconsistent
state. Reasons for automatic blocking of async signals carry over to
> I agree with your assessment of the problems with interruptible
> operations in GHC: that it is impossible to completely block async
> exceptions across a computation. We could certainly add a way to
> do this. Is that the substance of your objection to GHC's async
> exception mechanism?
Regarding interruptible operations, this and one more thing that I
haven't written there:
The fact that some function uses an interruptible operation internally
is a visible aspect of its behavior, both in GHC design and in mine.
This means that choosing which operations are interruptible should be
done carefully: even if some operation blocks the thread, it might be
a bad choice for an interruption point, because usage of some blocking
operations should better not have to be exposed. In my case such
blocking but uninterruptible operations include waiting for a mutex,
and waiting for a lazy variable, among others.
But Concurrent Haskell uses a single construct of MVars as mutexes,
semaphores, or communication channels. The runtime can't recognize the
pattern of usage to distinguish these cases.
__("< Marcin Kowalczyk
\__/ qrczak at knm.org.pl
More information about the Haskell-prime