This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
ARM atomicity.h
- To: libstdc++ at gcc dot gnu dot org
- Subject: ARM atomicity.h
- From: Robin Farine <acnrf at dial dot eunet dot ch>
- Date: 04 Jul 2001 18:52:03 +0200
Hi,
The atomic operations defined in cpu/arm/bits/atomicity.h do not seem really
atomic to me.
For instance, consider the __atomic_add() routine below and two threads T1 and
T2. The execution sequence of these threads illustrated below the __atomic_add()
routine shows how T1 can trash the effect of T2. First, the counter location
(*__mem) holds 0 and T1 enters __atomic_add() but just before the swp, a
reschedule promotes T2 which in turn enters __atomic_add() and increment the
counter in one shot. Later, T1 resumes it execution, performs the swp and cmp
instructions but gets suspended *before* the swpne instruction. T2 comes again
and adds 2 to the counter. When T1 executes the swpne, it restores the counter
to the *old* value 1 which screws up everything.
This example could happen if T2 has a greater priority than T1 and an interrupt
handler wakes up T2 in response of a device event.
Please forgive me if I completely missed the point here.
Regards,
Robin
static inline void
__attribute__ ((__unused__))
__atomic_add (volatile _Atomic_word *__mem, int __val)
{
_Atomic_word __tmp, __tmp2, __tmp3;
__asm__ __volatile__ (
"\n"
"0:\t"
1 "ldr %0, [%3] \n\t"
2 "add %1, %0, %4 \n\t"
3 "swp %2, %1, [%3] \n\t"
4 "cmp %0, %2 \n\t"
5 "swpne %1, %2, [%3] \n\t"
6 "bne 0b \n\t"
7 ""
: "=&r"(__tmp), "=&r"(__tmp2), "=&r"(__tmp3)
: "r" (__mem), "r"(__val)
: "cc", "memory");
}
Example of sequence that produces an invalid result (*__mem == 2 instead of 4 at
the end):
T1 (%0 %1 %2) T2 (%0 %1 %2) *__mem
1 (x x x) __val=1 0
2 (0 x x)
3 (0 1 x) <-- reschedule
1 (x x x) __val=1
2 (0 x x)
3 (0 1 x)
4 (0 1 0) 1
5 (0 1 0)
6 (0 1 0)
7 (0 1 0)
... <-- reschedule
4 (0 1 1) 1
5 (0 1 1) <-- reschedule
1 (x x x) __val=2
2 (1 x x)
3 (1 3 x)
4 (1 3 1) 3
5 (1 3 1)
6 (1 3 1)
7 (1 3 1)
.... <-- reschedule
6 (0 3 1) 1
1 (0 3 1)
2 (1 3 1)
3 (1 2 1)
4 (1 2 1) 2
5 (1 2 1)
6 (1 2 1)
7 (1 2 1)
....