Improving the speed of Thread interrupt checking
Alexander Turner
nerdscentral at gmail.com
Sat May 11 01:37:21 PDT 2013
Charles,
Would not atomic increment and atomic decrement solve the multi-interrupt
issue you suggest here? Such an approach is a little more costly because in
the case of very high contention the setters need to spin to get the
increment/decrement required if using pure CAS. That could be a lot of
cache flushes - but it would then be strictly correct (I don't actually
know how gcc or any other compiler goes about implementing add/sub):
__sync_fetch_and_sub
__sync_fetch_and_add
- AJ
On 11 May 2013 09:26, Charles Oliver Nutter <headius at headius.com> wrote:
> On Sat, May 11, 2013 at 2:49 AM, Jeroen Frijters <jeroen at sumatra.nl>wrote:
>
>> I believe Thread.interrupted() and Thread.isInterrupted() can both be
>> implemented without a lock or CAS.
>>
>> Here are correct implementations:
>>
> ...
>
>> Any interrupts that happen before we clear the flag are duplicates that
>> we can ignore and any that happen after are new ones that will be returned
>> by a subsequent call. The key insight is that the interruptPending flag can
>> be set by any thread, but it can only be cleared by the thread it applies
>> to.
>>
>
> This may indeed be the case. My goal with considering CAS was to maintain
> the full behavioral constraints of the existing implementation, which will
> never clear multiple interrupts at once, regardless of duplication.
>
> If your assumption holds, then Vitaly's case is not a concern. His case,
> again:
>
> * Thread A retrieves interrupt status
> * Thread B sets interrupt, but cannot clear it from outside of thread A
> * Thread A clears interrupt
>
> The end result of this sequence is indeed different if A's get + clear are
> not atomic: the interrupt status after A returns would be clear rather than
> set. However, *it does not really matter*.
>
> If we look at the *caller* of the interrupt checking, things become
> obvious.
>
> Mutexed/atomic version:
>
> * Thread A makes a call to Thread.interrupt to get and clear interrupt
> status
> * Thread A acquires lock and gets interrupt status and clears it atomically
> * Thread A returns from Thread.interrupt, reporting that the thread was
> interrupted, and the caller knows it has been cleared
> * Before Thread A proceeds any further (raising an error, etc), thread B
> comes in and sets interrupt status.
>
> The result is that the interrupt is set, and there's nothing A can do to
> ensure it has been cleared. A subsequent call to Thread.interrupted can be
> preempted *after* the clear anyway.
>
> So, a different preemption order with mutex:
>
> * Thread A makes a call to Thread.interrupt to get and clear interrupt
> status
> * Before the mutex is acquired, Thread B swoops in, setting interrupt
> status.
> * Thread A proceeds to acquire mutex and only sees a single interrupt bit;
> it gets status and clears it.
>
> So even an atomic version does nothing to guarantee what the interrupt
> status will be after all threads are finished fiddling with the interrupt
> bit; preemption can happen before or after the mutexed operation, producing
> different results in both cases.
>
> Ultimately, this may actually be a flaw with the way Thread interrupt
> works in the JVM. If there's potential for interrupt to be set twice or
> more, the interrupted thread can't ever guarantee that the interrupt has
> been cleared.
>
> In practice, this flaw may not matter; if you have one or more external
> threads that interrupt a target thread N times, you have to assume (and
> have always had to assume) the target thread will see anywhere from 1 to N
> of those interrupts, depending on preemption. This does not change with any
> of the proposed implementations. The only safe situation is when you know
> interruption will happen only once within a critical section of code.
>
> Put simply (tl;dr): even with atomic/mutexed interrupt set+clear, you
> can't make any guarantees about how many interrupts will be seen if
> multiple interrupts are attempted. If true, the mutex in the current
> implementation is 100% useless.
>
> - Charlie
>
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20130511/1b7d368c/attachment.html
More information about the mlvm-dev
mailing list