This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: Using __kuser_cmpxchg
On Thu, 15 Nov 2007, Andrew Haley wrote:
> Nicolas Pitre writes:
> > On Thu, 15 Nov 2007, Andrew Haley wrote:
> >
> > In the mean time you can work around it by using a mutex around the
> > thread state modification instead of using cmpxchg on it. Or if your
> > platform is ARMv6 or higher then you won't get those spurious false
> > negatives.
>
> Ah, OK, that's interesting: it sounds like you understand under what
> circumstances it may fail "spuriously".
Heh, I wrote that code (and comment). :-)
> What are these?
On a pre-ARMv6 processor, there is no way to implement a truly atomic
user space cmpxchg without disabling interrupts, which can be done only
from kernel space. And going to kernel space only for atomically
modifying a single value in memory is rather prohibitive.
However, on a non SMP machine, the only thing that can break user space
atomicity is a processor exception. When an exception occurs because of
an IRQ or a page fault, the kernel may well decide to schedule another
user process or thread unexpectedly.
So we cheat a bit by simply performing the load+compare+store with
plain standard instructions as follows:
teq ip, ip @ set Z flag
ldr ip, [r2] @ load current val
add r3, r2, #1 @ prepare store ptr
teqeq ip, r0 @ compare with oldval if still allowed
streq r1, [r3, #-1]! @ store newval if still allowed
subs r0, r2, r3 @ if r2 == r3 the str occured
But there is a twist such that if ever an exception occurs during that
sequence, the Z flag is cleared by the exception handler before that
sequence is resumed and the store won't occur. The Z flag might be
cleared even if the comparison was good and would still be so after the
exception returns though, which is the source of the false negative
return.
The solution to fix that flaw would involve the exception handler
backing the pc if it is found to be within the critical area so to
perform the load again.
Nicolas