This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
is it a bug of /glibc/sysdeps/arm/atomicity.h ?
- From: "Hu, Boris" <boris dot hu at intel dot com>
- To: "Linux-Arm (E-mail)" <linux-arm at lists dot arm dot linux dot org dot uk>, "Libc-Alpha (E-mail)" <libc-alpha at sources dot redhat dot com>
- Date: Mon, 17 Feb 2003 17:25:48 +0800
- Subject: is it a bug of /glibc/sysdeps/arm/atomicity.h ?
In /glibc/sysdeps/arm/atomicity.h
65 static inline int
66 __attribute__ ((unused))
67 compare_and_swap (volatile long int *p, long int oldval, long int
newval)
68 {
69 int result, tmp;
70 __asm__ ("\n"
71 "0:\tldr\t%1,[%2]\n\t"
72 "mov\t%0,#0\n\t"
73 "cmp\t%1,%4\n\t"
74 "bne\t1f\n\t"
75 "swp\t%0,%3,[%2]\n\t"
76 "cmp\t%1,%0\n\t"
77 "swpne\t%1,%0,[%2]\n\t"
78 "bne\t0b\n\t"
79 "mov\t%0,#1\n"
80 "1:"
81 : "=&r" (result), "=&r" (tmp)
82 : "r" (p), "r" (newval), "r" (oldval)
83 : "cc", "memory");
84 return result;
85 }
let us consider the following scenario. Suppose there are three thread
pathes.
Init: *p = 0
T1 compare_and_swap(p, 0, 1) ;
T2 compare_and_swap(p,0,1);
T3 compare_and_swap(p,1,2);
T1::
static inline int compare_and_swap (volatile long int *p,
long int oldval, long int newval)
{
int result, tmp;
__asm__ ("\n"
"0:\tldr\t%1,[%2]\n\t"
"mov\t%0,#0\n\t"
"cmp\t%1,%4\n\t"
"bne\t1f\n\t" // if now, in T2, *p= 1;
"swp\t%0,%3,[%2]\n\t"
"cmp\t%1,%0\n\t" // if now, in T3 *p = 2
"swpne\t%1,%0,[%2]\n\t" // *p = 1 ; so the modification
of T3 will be overwritten. ???
"bne\t0b\n\t"
"mov\t%0,#1\n"
"1:"
: "=&r" (result), "=&r" (tmp)
: "r" (p), "r" (newval), "r" (oldval)
: "cc", "memory");
return result;
}
any opinion? thanks.
Boris
=========================
To know what I don't know
To learn what I don't know
To contribute what I know
=========================