Thread (29 messages) 29 messages, 6 authors, 2009-09-18

LDREX/STREX and pre-emption on SMP hardware

flat view

From: catalin.marinas@arm.com (Catalin Marinas)
Date: 2009-09-14 14:29:36

On Mon, 2009-09-14 at 15:23 +0100, Russell King - ARM Linux wrote:
On Mon, Sep 14, 2009 at 11:06:13AM +0100, Catalin Marinas wrote:
quoted
On Mon, 2009-09-14 at 11:00 +0100, Russell King - ARM Linux wrote:
quoted
On Mon, Sep 14, 2009 at 02:43:53AM +0100, Jamie Lokier wrote:
quoted
Catalin Marinas wrote:
quoted
With interrupts (I1, I2 interrupt handlers)

I1			I2
LDREX
			LDREX
			STREX (succeeds)
STREX (fails)

In the interrupt case, they are nested so the STREX in I2 is always
executed before STREX in I1 (you can extrapolate with several nested
interrupts).
This assumes LDREX/STREX are always called in pairs.  But this is in
fact _not_ the case.  Take a look at atomic_cmpxchg:

	do {
		__asm__ __volatile__("@ atomic_cmpxchg\n"
		"ldrex	%1, [%2]\n"
		"mov	%0, #0\n"
		"teq	%1, %3\n"
		"strexeq %0, %4, [%2]\n"
		    : "=&r" (res), "=&r" (oldval)
		    : "r" (&ptr->counter), "Ir" (old), "r" (new)
		    : "cc");
	} while (res);

In the case where ptr->counter != old, STREX is not executed, and the
do{...}while loop does not loop.  Thus LDREX/STREX aren't paired.
It doesn't matter though - consider two threads using LDREX on the same
location:

	T1		T2
	LDREX
			LDREX
			STREXEQ (not satsified)
	STREX
As I replied to Jamie on a similar issue, you can have:

T1			T2
LDREX
			LDREX
			STREXEQ (satisfied, succeeds)
			LDREX
			STREXEQ (not satisfied)
STREX (succeeds)

Though this may be an unlikely sequence.
Actually, both of these can't happen because they imply a context switch
and a context switch clears the exclusive monitor.  
T2 here in an interrupt handler (misleadingly called thread, though the
architecture people here in ARM just call everything a thread of
execution). Jamie's reply here was referring to interrupt handlers.
So the real sequence
is:
quoted
quoted
	T1		T2
	LDREX
		CLREX
quoted
quoted
			LDREX
			STREXEQ (not satsified)
		CLREX
quoted
quoted
	STREX
which results in the STREX not succeeding.  Ditto for your case.
The other case where I replied was discussing the need for CLREX at
context switch and that's needed to get the correct behaviour (T1 and T2
are OS threads in this case).

-- 
Catalin
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help