Recent additions/changes (see personal repo) Marc Nieper-Wißkirchen (11 Nov 2022 17:19 UTC)
Re: Recent additions/changes (see personal repo) Shiro Kawai (14 Nov 2022 19:05 UTC)
Re: Recent additions/changes (see personal repo) Marc Nieper-Wißkirchen (14 Nov 2022 19:11 UTC)
Re: Recent additions/changes (see personal repo) Shiro Kawai (15 Nov 2022 08:31 UTC)
Re: Recent additions/changes (see personal repo) Marc Feeley (17 Nov 2022 13:22 UTC)
Re: Recent additions/changes (see personal repo) Marc Nieper-Wißkirchen (17 Nov 2022 13:51 UTC)
Re: Recent additions/changes (see personal repo) Marc Feeley (17 Nov 2022 14:24 UTC)
Re: Recent additions/changes (see personal repo) Marc Nieper-Wißkirchen (17 Nov 2022 14:44 UTC)
Re: Recent additions/changes (see personal repo) Marc Feeley (17 Nov 2022 15:38 UTC)
Re: Recent additions/changes (see personal repo) Marc Nieper-Wißkirchen (17 Nov 2022 16:26 UTC)
Re: Recent additions/changes (see personal repo) Shiro Kawai (17 Nov 2022 20:12 UTC)
Re: Recent additions/changes (see personal repo) Marc Nieper-Wißkirchen (17 Nov 2022 20:32 UTC)
Re: Recent additions/changes (see personal repo) Shiro Kawai (17 Nov 2022 23:02 UTC)
Re: Recent additions/changes (see personal repo) Shiro Kawai (17 Nov 2022 23:13 UTC)
Re: Recent additions/changes (see personal repo) Marc Feeley (17 Nov 2022 20:43 UTC)

Re: Recent additions/changes (see personal repo) Marc Nieper-Wißkirchen 17 Nov 2022 13:51 UTC

Am Do., 17. Nov. 2022 um 14:22 Uhr schrieb Marc Feeley
<xxxxxx@iro.umontreal.ca>:
>
>
> > On Nov 11, 2022, at 12:19 PM, Marc Nieper-Wißkirchen <xxxxxx@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.