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 <head...@headius.com> wrote: > On Sat, May 11, 2013 at 2:49 AM, Jeroen Frijters <jer...@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@openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > >
_______________________________________________ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev