[MLton] interrupted system call
Matthew Fluet
fluet@cs.cornell.edu
Sat, 27 Mar 2004 15:08:16 -0500 (EST)
O.k., things seem to have quiesced. I just wanted to review the decisions
that seem to have been reached and changes that need to be made.
Those functions in the Basis Libary that correspond directly to system
calls should have predictable (if slightly complicated) semantics. The
principal concerns are
(1) system calls that are interrupted by signals should, by default, be
restarted; the alternative is to raise SysError (as would normally
be done by a system call that returns ~1). This behavior will be
determined dynamically by the value of
MLton.Signal.restart : bool ref.
+ Another alternative would be to make this behavior a compile time
decision. On argument against doing so is that sigaction
determines this behavior dynamically, by the SA_RESTART flag, so
it should be dynamic here as well. On the other hand, I don't
think we could support SA_RESTART like behavior on the granularity
of individual signal handlers.
(2) signal handlers should always get a chance to run (when outside a
critical region). If a system call is interrupted by a signal, then
the SML signal handler will run before the call is restarted or
SysError is raised; that is, before the MLton.Signal.restart check.
(3) a system call that must be restarted while in a critical
section will be restarted with the ML handled signals blocked (and
the previously blocked signals will be saved). This encourages the
system call to complete, allowing the program to make progess towards
leaving the critical section where the signal can be handled. If the
system call completes, the set of blocked signals are restored to
those previously blocked.
To support this, we have identified the following changes:
Runtime:
- blocking and unblocking of signals in gc.c must respect those signals
blocked by the program. This is currently broken.
Backend:
- atomicEnd will invoke GC_gc when leaving a critical section when a
signalIsPending and canHandle == 0. This requires a change in ssa to
rssa.
+ the translation of atomicEnd can actually be predicated upon
handlesSignals. We are keeping the canHandle inc and dec because
it's useful for asserts. But, there is no need to put in a GC safe
point if signals aren't being handled.
+ We ought to verify that limit check uses GC_gc to decycle loops;
however, this doesn't really matter. atomicEnd gets translated
into a branch, with GC_gc down only one. So the restart loop
remains unbroken by GC_gc.
Basis Library:
- MLton.Signal.restart
- MLton.Signal.Mask.{getBlocked, handled}
- Posix.Error.syscall (in some form)
- put Posix.Error.syscall wrapper around system calls
Have I missed anything?