[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?