Interrupting repl in Slime

Alessio Stalla alessiostalla at gmail.com
Mon Apr 11 05:00:51 UTC 2022


I don't get why ABCL needs a volatile flag where it could just use
Thread.interrupted() (
https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#interrupted--).
I guess the latter cannot be less efficient than a userland solution like
ABCL's.

On Mon, 11 Apr 2022 at 04:32, Alan Ruttenberg <alanruttenberg at gmail.com>
wrote:

> Ok, I think I cracked it. Check out
> https://github.com/armedbear/abcl/pull/482
> Alan
>
>
> On Thu, Apr 7, 2022 at 9:26 PM Alan Ruttenberg <alanruttenberg at gmail.com>
> wrote:
>
>>
>> Some more: This is where the code for checking for interrupt is generated
>> (defun maybe-generate-interrupt-check ()
>>   (unless (> *speed* *safety*)
>>     (let ((label1 (gensym)))
>>
>> * (emit-getstatic +lisp+ "interrupted" :boolean)      (emit 'ifeq label1)*
>>       (emit-invokestatic +lisp+ "handleInterrupt" nil nil)
>>       (label label1))))
>>
>> I'm thinking, since interrupt-lisp isn't used anyways, modify it to take
>> a thread argument.
>> In interrupt-lisp, call setInterrupted with that thread.
>> In Lisp.java change the type of interrupted and change setInterrupted to
>> take a thread argument, setting Lisp.interrupted to it.
>>
>> Then, in the maybe-generate-interrupt-check don't Lisp.interrupted check
>> as boolean, check if eq to current thread. The current thread can be made
>> accessible adding  (ensure-thread-var-initialized), which puts it into a
>> local at the beginning of the function. Access it with  (aload *thread*)
>> which puts it on the stack. I think this means that the lines underlined
>> above get replaced with.
>>
>>   (ensure-thread-var-initialized)
>>   (emit-getstatic +lisp+ "interrupted" +lisp-thread+)
>>   (aload *thread*)
>>   (emit 'if_acmpne label1)
>>
>> In Lisp.handleInterrupts it's setInterrupted(null) vs
>> setInterrrupted(false);
>>
>> As stated, this mechanism is strictly to enable control-c.
>>
>> However, maybe we could have it help thread-interrupt respond more
>> quickly.  in Lisp.handleInterrupts.
>> check thread.isInterrupted and call processThreadInterrupts (the thing
>> that is done now) otherwise break.
>> Have the implementation of thread-interrupt do what it does now and also
>> call interrupt-lisp to get it noticed.
>> ---
>>
>> I haven't tried this. Mostly I'm fumbling around trying to get enough
>> information to do this. I don't know java byte code except what I learned
>> researching this.
>> I don't know if there are pitfalls. I don't know why something like this
>> wouldn't have been done in the first place.
>>
>> The only thing I can currently think of is that there could be a race
>> condition on setting Lisp.interrupted.
>> The consequence of that is that if there were two quick
>> thread-interrupts, only one of the threads would
>> do the quick response. The other would be processed in the way it
>> currently is.
>>
>> Anyways, comments solicited.
>> Alan
>>
>>
>>
>>
>>
>> On Thu, Apr 7, 2022 at 1:21 PM Alan Ruttenberg <alanruttenberg at gmail.com>
>> wrote:
>>
>>> The functions that ABCL uses in Threads.java are thread.interrupt and
>>> thread.isInterrupted. It overrides interrupt and isInterrupted to implement
>>> interrupt-thread - by saving away the function the target thread is to be
>>> interrupted with.  Remember, interrupt-thread isn't executed by the thread
>>> to be interrupted, it's called from another thread. The receiving thread
>>> handles InterruptedException, which is only called on explicit check of
>>> interrupt state or from sleep or wait.
>>>
>>> Separately, in Lisp.Java there's setInterrupted and handleInterrupt that
>>> don't use the java mechanism. Rather setInterrupted sets a static volatile
>>> Lisp.interrupted, handleInterrupted clears the variable and calls break.
>>> setInterrupted, as I said, is only called from interrupt-lisp. Code
>>> generation inserts checks of Lisp.interrupted and calls handleInterrupted
>>> if it is set. I have a feeling that this part was done so that frequent
>>> interrupt checks could be made without taking the performance hit of a
>>> synchronized method call. Remember this check is done inside every loop
>>> iteration. The check for Lisp.interrupted is a volatile read, which in most
>>> cases is handled in the cache. A write to the volatile invalidates the
>>> cache forcing the new value to be read from memory. So much less expensive.
>>>
>>> It would be useful to know the history of how it came to be that there
>>> are two different interrupt mechanisms.
>>>
>>>
>>>
>>> On Thu, Apr 7, 2022 at 7:21 AM Alessio Stalla <alessiostalla at gmail.com>
>>> wrote:
>>>
>>>> No, I mean
>>>> https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#interrupted--
>>>>
>>>> The only deprecated methods are suspend, resume and stop. The interrupt
>>>> machinery is what developers are supposed to use (at least when not using
>>>> some higher-level framework). It's a form of cooperative multitasking,
>>>> since a thread can completely ignore the interrupt. However, given we have
>>>> control over Lisp threads, we can play nice with that convention, and maybe
>>>> offer a without-interrupts special form for performance-critical code where
>>>> the developer assumes the responsibility of checking for interrupts in
>>>> selected moments.
>>>>
>>>> On Thu, 7 Apr 2022 at 11:42, Mark Evenson <evenson at panix.com> wrote:
>>>>
>>>>>
>>>>>
>>>>> > On Apr 7, 2022, at 08:22, Alessio Stalla <alessiostalla at gmail.com>
>>>>> wrote:
>>>>> >
>>>>> > […] Java threads already natively have an interrupt flag.
>>>>>
>>>>> Presumably, the [Thread.State enumeration] is what you are referring
>>>>> to. I have checked that it is present in openjdk{8,11,17}, and not marked
>>>>> as deprecated.
>>>>>
>>>>> [1]:
>>>>> https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.State.html
>>>>>
>>>>> --
>>>>> "A screaming comes across the sky.  It has happened before but there
>>>>> is nothing
>>>>> to compare to it now."
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/armedbear-devel/attachments/20220411/1f187ada/attachment-0001.html>


More information about the armedbear-devel mailing list