Am Do., 17. Nov. 2022 um 14:22 Uhr schrieb Marc Feeley
<fee...@iro.umontreal.ca>:
>
>
> > On Nov 11, 2022, at 12:19 PM, Marc Nieper-Wißkirchen 
> > <marc.nie...@gmail.com> wrote:
> >
> > I have documented thread-interrupt! in 5.14.6.
> >
> > Thread-exit! is now renamed to thread-stop!.
> >
> > I hope that only editorial changes remain before we finalize this.
> >
>
> I have problems understanding the spec for thread-interrupt!:
>
> (thread-interrupt! thread thunk)      procedure
>
> Schedules an interrupt for thread for when the current-interrupt-level of 
> thread is zero. The current continuation of thread is then replaced by a 
> continuation that records the values it receives, invokes thunk with no 
> arguments, discards its values, and then yields the recorded values to the 
> original continuation.
>
> Note: An interrupt can occur while a thread is blocked waiting on a condition 
> variable.
>
>
> It mentions “replacing” the current continuation of the target thread by a 
> new one.  I don’t understand that model which seems to assume that the 
> computation moves from continuation to continuation (i.e. that calling a 
> continuation marks the beginning of a computational step).  I think it also 
> assumes that every point where a continuation is called is a “safe point” 
> where the Scheme VM is in a consistent state.  But when a program is written 
> in continuation passing style the implicit continuations are never called 
> because the computation is strictly a sequence of tail calls with no returns. 
>  Also the simple infinite loop (let loop () (loop)) never calls a 
> continuation… so does that mean it can’t be interrupted?

A continuation is not called; a piece of code is evaluated in a
continuation.  After each evaluation step (the spec is silent on how
fine-grained this is), there will again be a continuation (possibly
the same) waiting for the result of some evaluation step.  In essence,
I mean the same as your syntactic replacement of <expr> by (begin
(poll-interrupts!) <expr>).  To make it precise, we would really have
to amend the formal semantics of Scheme.

> I think a better way to explain it is that every expression <expr> in the 
> program is conceptually treated as (begin (poll-interrupts!) <expr>) and then 
> give a definition of (poll-interrupts!) that checks the 
> current-interrupt-level and calls any pending interrupt thunks.  Also, the 
> spec must explain that (for performance reasons) the implementation may 
> postpone the polling, but only for a bounded time.  An interrupt check must 
> also be performed when the interrupt-level is set to 0, either due to a call 
> (enable-interrupts!) or (current-interrupt-level 0) or on the way out of a 
> binding done with (parameterize ((current-interrupt-level …)) …) or on the 
> way in of a binding done with (parameterize ((current-interrupt-level 0)) …).

The latter is, in general, too strict; as the body of parameterize is
in tail context when parameterize is in tail context, every return
from a call can effectively set the interrupt level to 0, meaning that
interrupts would have to be polled at every return.

> The second comment is about the note “An interrupt can occur while a thread 
> is blocked waiting on a condition variable”.  A thread can be interrupted in 
> the “runnable” and “blocked” states, not just blocked on a condition variable 
> (for example it could be blocked on a mutex, or sleeping).  The only 
> situations where it can’t be interrupted is when the interrupt level is not 
> 0, or when the state of the thread is “new” (i.e. created but not yet made 
> runnable) and “terminated”.

I called it a "note" precisely because it is not exhaustive.  I will
expand the note so that there are no misunderstandings.

> Finally, the current-interrupt-level mechanism may be too coarse.  Perhaps an 
> interrupt level per interrupt source might be needed for some applications.  
> I think the current design is OK for now if current-interrupt-level is seen 
> as a “global” interrupt masking machanism.  A future SRFI can add a mechanism 
> that is more fine-grained.  I think this could be implemented on top of the 
> interrupt mechanism of this SRFI.

Having future SRFIs for, say, keyboard or timer interrupts makes sense.

Ultimately, a timer would call thread-interrupt! but before, it would
have to poll a timer-specific interrupt level parameter.  Do you have
an idea how to make this polling efficient without further primitives?

> I’m slowed down by other things right now so I can’t yet comment on the rest 
> of SRFI 226.

Thank you for your valuable comments so far!

I would like to get SRFI 226 finalized within the following weeks.

Reply via email to