This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
[PATCH] PPC atomic.h add compare_exchange_val forms
- From: Steven Munroe <sjmunroe at us dot ibm dot com>
- To: libc-alpha <libc-alpha at sources dot redhat dot com>
- Date: Tue, 15 Apr 2003 10:56:53 -0500
- Subject: [PATCH] PPC atomic.h add compare_exchange_val forms
- Organization: IBM Linux Developement
- Reply-to: sjmunroe at vnet dot ibm dot com
Changes in nptl/pthreadP.h (introduced __do_cancel which uses
THREAD_ATOMIC_BIT_SET) require atomic_compare_and_exchange_val_acq to be
explicitely implemented for all architectes. PPC32 and PPC64 did not
specifically define this form. The attached patch implement
atomic_compare_and_exchange_val_acq for 32-bit (both PPC32/PPC64) and 64-bit
(PPC64 only).
2003-04-15 Steven Munroe <sjmunroe at us dot ibm dot com>
* sysdeps/powerpc/bits/atomic.h
[__powerpc64] (__arch_compare_and_exchange_val_64_acq): Define.
[! __powerpc64] (__arch_compare_and_exchange_val_64_acq): Defined
as abort stub.
(__arch_compare_and_exchange_val_32_acq): Define.
(atomic_compare_and_exchange_val_acq): Define.
--
Steven Munroe
sjmunroe at us dot ibm dot com
Linux on PowerPC-64 Development
GLIBC for PowerPC-64 Development
diff -urN libc23-cvstip-20030414/sysdeps/powerpc/bits/atomic.h libc23/sysdeps/powerpc/bits/atomic.h
--- libc23-cvstip-20030414/sysdeps/powerpc/bits/atomic.h 2003-03-28 01:17:02.000000000 -0600
+++ libc23/sysdeps/powerpc/bits/atomic.h 2003-04-15 08:28:35.000000000 -0500
@@ -109,6 +109,24 @@
__tmp != 0; \
})
+#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ ({ \
+ __typeof (*(mem)) __tmp; \
+ __typeof (mem) __memp = (mem); \
+ __asm __volatile (__ARCH_REL_INSTR "\n" \
+ "1: ldarx %0,0,%1\n" \
+ " cmpd %0,%2\n" \
+ " bne 2f\n" \
+ " stdcx. %3,0,%1\n" \
+ " bne- 1b\n" \
+ "2: " __ARCH_ACQ_INSTR \
+ : "=&r" (__tmp) \
+ : "b" (__memp), "r" (oldval), "r" (newval) \
+ : "cr0", "memory"); \
+ __tmp; \
+ })
+
+
# define __arch_atomic_exchange_64(mem, value) \
({ \
__typeof (*mem) __val; \
@@ -170,6 +188,9 @@
# define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval) \
(abort (), 0)
+# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ (abort (), 0)
+
# define __arch_atomic_exchange_64(mem, value) \
({ abort (); (*mem) = (value); })
# define __arch_atomic_exchange_and_add_64(mem, value) \
@@ -178,6 +199,25 @@
({ abort (); (*mem)--; })
#endif
+
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+ ({ \
+ __typeof (*(mem)) __tmp; \
+ __typeof (mem) __memp = (mem); \
+ __asm __volatile (__ARCH_REL_INSTR "\n" \
+ "1: lwarx %0,0,%1\n" \
+ " cmpw %0,%2\n" \
+ " bne 2f\n" \
+ " stwcx. %3,0,%1\n" \
+ " bne- 1b\n" \
+ "2: " __ARCH_ACQ_INSTR \
+ : "=&r" (__tmp) \
+ : "b" (__memp), "r" (oldval), "r" (newval) \
+ : "cr0", "memory"); \
+ __tmp; \
+ })
+
+
#define __arch_atomic_exchange_32(mem, value) \
({ \
__typeof (*mem) __val; \
@@ -220,6 +260,18 @@
})
+#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
+ ({ \
+ __typeof (*(mem)) __result; \
+ if (sizeof (*mem) == 4) \
+ __result = __arch_compare_and_exchange_val_32_acq(mem, newval, oldval); \
+ else if (sizeof (*mem) == 8) \
+ __result = __arch_compare_and_exchange_val_64_acq(mem, newval, oldval); \
+ else \
+ abort (); \
+ __result; \
+ })
+
#define atomic_exchange(mem, value) \
({ \
__typeof (*(mem)) __result; \