From 7133957fe856f42c356c6e46c52d2ea8063ae067 Mon Sep 17 00:00:00 2001 From: Stefan Liebler Date: Fri, 20 Feb 2015 10:48:06 +0100 Subject: s390: Use generic lowlevellock-futex.h * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Include and remove macros and functions that are now defined there. (SYS_futex): Remove. (lll_compare_and_swap): Remove. * sysdeps/s390/bits/atomic.h (atomic_exchange_acq): Define. --- sysdeps/s390/bits/atomic.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'sysdeps/s390/bits') diff --git a/sysdeps/s390/bits/atomic.h b/sysdeps/s390/bits/atomic.h index a85288280c..16c8c54b94 100644 --- a/sysdeps/s390/bits/atomic.h +++ b/sysdeps/s390/bits/atomic.h @@ -77,3 +77,44 @@ typedef uintmax_t uatomic_max_t; # define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ (abort (), (__typeof (*mem)) 0) #endif + +/* Store NEWVALUE in *MEM and return the old value. */ +/* On s390, the atomic_exchange_acq is different from generic implementation, + because the generic one does not use the condition-code of cs-instruction + to determine if looping is needed. Instead it saves the old-value and + compares it against old-value returned by cs-instruction. */ +#ifdef __s390x__ +# define atomic_exchange_acq(mem, newvalue) \ + ({ __typeof (mem) __atg5_memp = (mem); \ + __typeof (*(mem)) __atg5_oldval = *__atg5_memp; \ + __typeof (*(mem)) __atg5_value = (newvalue); \ + if (sizeof (*mem) == 4) \ + __asm __volatile ("0: cs %0,%2,%1\n" \ + " jl 0b" \ + : "+d" (__atg5_oldval), "=Q" (*__atg5_memp) \ + : "d" (__atg5_value), "m" (*__atg5_memp) \ + : "cc", "memory" ); \ + else if (sizeof (*mem) == 8) \ + __asm __volatile ("0: csg %0,%2,%1\n" \ + " jl 0b" \ + : "+d" ( __atg5_oldval), "=Q" (*__atg5_memp) \ + : "d" ((long) __atg5_value), "m" (*__atg5_memp) \ + : "cc", "memory" ); \ + else \ + abort (); \ + __atg5_oldval; }) +#else +# define atomic_exchange_acq(mem, newvalue) \ + ({ __typeof (mem) __atg5_memp = (mem); \ + __typeof (*(mem)) __atg5_oldval = *__atg5_memp; \ + __typeof (*(mem)) __atg5_value = (newvalue); \ + if (sizeof (*mem) == 4) \ + __asm __volatile ("0: cs %0,%2,%1\n" \ + " jl 0b" \ + : "+d" (__atg5_oldval), "=Q" (*__atg5_memp) \ + : "d" (__atg5_value), "m" (*__atg5_memp) \ + : "cc", "memory" ); \ + else \ + abort (); \ + __atg5_oldval; }) +#endif -- cgit v1.2.3