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)
|
> On Nov 17, 2022, at 9:44 AM, Marc Nieper-Wißkirchen <xxxxxx@gmail.com> wrote: > > Am Do., 17. Nov. 2022 um 15:24 Uhr schrieb Marc Feeley > <xxxxxx@iro.umontreal.ca>: >> >> >> Marc >> >> >> >>> On Nov 17, 2022, at 8:51 AM, Marc Nieper-Wißkirchen <xxxxxx@gmail.com> wrote: >>> >>> 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 understand. In that case it would be good to add a reminder of this stepping model. > > Okay, will do! > >> >>>> 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. >> >> Not every return, just a return that returns to a continuation marked with a “parameterize”. This is the (usual?) trick to avoid administrative overheads when returning to a special continuation (such as a continuation that is no longer on the stack). > > You are right; but what is the reason you want an interruption to be > performed immediately? And without any synchronization between the > interrupting and the interrupted thread, "immediately" is not even > clear to me. > The important point is not that the interrupt check is done immediately. But there must be a garantee that as soon as a thread allows interrupts, i.e. the level reaches 0, the thread can’t delay handling the interrupt for more than a bounded time. The situation that is problematic is: (begin (parameterize ((current-interrupt-level 1)) A) … (parameterize ((current-interrupt-level 1)) B) …) Assume an interrupt happens during the evaluation of expression A, and that both A and B have a long execution time. We want the interrupt to be handled after the first parameterize and before the second parameterize. An easy way to do that is to force a check when the current-interrupt-level reaches 0. Another way would be when the level is being changed to >= 1 and it is currently 0. If that’s not garanteed then I think it would be legitimate to handle these two expressions equivalently: (let loop () (parameterize ((current-interrupt-level 1)) A) (loop)) (parameterize ((current-interrupt-level 1)) (let loop () A (loop))) and this would be unusable. Marc