From 4b490b83f04560ac4b164ebf93c3583ca8248a7e Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Fri, 29 Jul 2022 18:10:05 +0300 Subject: Ensure result of AO_test_and_set is always AO_TS_CLEAR or AO_TS_SET (fix of commit cbbf8633) According to the GCC manual, __atomic_test_and_set() result type is Bool, thus it is not guaranteed to return AO_TS_SET value. (E.g., the function may return 1 while AO_TS_SET is 255, as observed on sparc64 with gcc-12.) * src/atomic_ops/sysdeps/gcc/generic.h [!AO_PREFER_GENERALIZED] (AO_test_and_set, AO_test_and_set_acquire, AO_test_and_set_release, AO_test_and_set_full): Return AO_TS_SET if __atomic_test_and_set() result is non-zero, AO_TS_CLEAR otherwise. --- src/atomic_ops/sysdeps/gcc/generic.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/atomic_ops/sysdeps/gcc/generic.h') diff --git a/src/atomic_ops/sysdeps/gcc/generic.h b/src/atomic_ops/sysdeps/gcc/generic.h index 00fd3ac..0a6d032 100644 --- a/src/atomic_ops/sysdeps/gcc/generic.h +++ b/src/atomic_ops/sysdeps/gcc/generic.h @@ -95,28 +95,32 @@ AO_INLINE AO_TS_VAL_t AO_test_and_set(volatile AO_TS_t *addr) { - return (AO_TS_VAL_t)__atomic_test_and_set(addr, __ATOMIC_RELAXED); + return (AO_TS_VAL_t)(__atomic_test_and_set(addr, __ATOMIC_RELAXED) + ? AO_TS_SET : AO_TS_CLEAR); } # define AO_HAVE_test_and_set AO_INLINE AO_TS_VAL_t AO_test_and_set_acquire(volatile AO_TS_t *addr) { - return (AO_TS_VAL_t)__atomic_test_and_set(addr, __ATOMIC_ACQUIRE); + return (AO_TS_VAL_t)(__atomic_test_and_set(addr, __ATOMIC_ACQUIRE) + ? AO_TS_SET : AO_TS_CLEAR); } # define AO_HAVE_test_and_set_acquire AO_INLINE AO_TS_VAL_t AO_test_and_set_release(volatile AO_TS_t *addr) { - return (AO_TS_VAL_t)__atomic_test_and_set(addr, __ATOMIC_RELEASE); + return (AO_TS_VAL_t)(__atomic_test_and_set(addr, __ATOMIC_RELEASE) + ? AO_TS_SET : AO_TS_CLEAR); } # define AO_HAVE_test_and_set_release AO_INLINE AO_TS_VAL_t AO_test_and_set_full(volatile AO_TS_t *addr) { - return (AO_TS_VAL_t)__atomic_test_and_set(addr, __ATOMIC_SEQ_CST); + return (AO_TS_VAL_t)(__atomic_test_and_set(addr, __ATOMIC_SEQ_CST) + ? AO_TS_SET : AO_TS_CLEAR); } # define AO_HAVE_test_and_set_full #endif /* !AO_PREFER_GENERALIZED */ -- cgit v1.2.1