This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: Using __kuser_cmpxchg
- From: Andrew Haley <aph at redhat dot com>
- To: Nicolas Pitre <nico at cam dot org>
- Cc: Paul Brook <paul at codesourcery dot com>, java at gcc dot gnu dot org, linux-arm-kernel at lists dot arm dot linux dot org dot uk
- Date: Thu, 15 Nov 2007 19:08:51 +0000
- Subject: Re: Using __kuser_cmpxchg
- References: <200711151759.lAFHxKa4027497@devserv.devel.redhat.com> <alpine.LFD.0.9999.0711151326510.21255@xanadu.home>
Nicolas Pitre writes:
> On Thu, 15 Nov 2007, Andrew Haley wrote:
>
> > Andrew Haley writes:
> > > Paul Brook writes:
> > > > For recent kernels there is a kernel helper you should use.
> > > > See __kernel_cmpxchg in linux/arch/arm/kernel/entry-armv.S
> > > >
> > > > Any kernel capable of running on armv6/v7 hardware should have this helper.
> > > > So should all targets on targets that define __ARM_EABI__
> > > >
> > > > So I suggest using the kernel helper for EABI and v6/v7 libraries, everyone
> > > > else will have to make do with the crappy old sequence.
> > >
> > > OK, I'll investigate this as soon as I get some time.
> >
> > It seems to be impossible to use this kernel helper because
> >
> > * - A failure might be transient, i.e. it is possible, although unlikely,
> > * that "failure" be returned even if *ptr == oldval.
> >
> > If this were to happen, the logic used to block and unblock threads
> > wouldn't work.
>
> Why?
These are threads in the Java sense, not in the POSIX sense.
Each thread has a permit.
"A call to park will return immediately if the permit is available,
consuming it in the process; otherwise it may block. A call to unpark
makes the permit available, if it was not already available. (Unlike
with Semaphores though, permits do not accumulate. There is at most
one.)
"Methods park and unpark provide efficient means of blocking and
unblocking threads that do not encounter the problems that cause the
deprecated methods Thread.suspend and Thread.resume to be unusable for
such purposes: Races between one thread invoking park and another
thread trying to unpark it will preserve liveness, due to the permit."
http://java.sun.com/javase/6/docs/api/java/util/concurrent/locks/LockSupport.html
Java threads can be in three states, PARKED, RUNNING, and PERMIT.
When unpark() is called, we do this:
/* If this thread is in state RUNNING, give it a permit and return
immediately. */
if (compare_and_swap
(ptr, Thread::THREAD_PARK_RUNNING, Thread::THREAD_PARK_PERMIT))
return;
/* If this thread is parked, put it into state RUNNING and send it a
signal. */
if (compare_and_swap
(ptr, Thread::THREAD_PARK_PARKED, Thread::THREAD_PARK_RUNNING))
{
...
To get back to ARM's __kuser_cmpxchg: if this second compare_and_swap
fails spuriously we won't unblock the thread.
Andrew.