From e3a01e02259ca0bb423631db56c71ded37ad5225 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller <schaller@strw.leidenuniv.nl> Date: Wed, 9 May 2018 14:16:54 +0200 Subject: [PATCH] Fixed the atomic min/max/add for floats that were incorrectly pushed earlier. --- src/atomic.h | 51 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/src/atomic.h b/src/atomic.h index 4e3407cc33..36e336b721 100644 --- a/src/atomic.h +++ b/src/atomic.h @@ -35,39 +35,48 @@ #define atomic_swap(v, n) __sync_lock_test_and_set(v, n) /** - * @param Atomic min operation on floats. + * @brief Atomic min operation on floats. */ -__attribute__((always_inline)) INLINE void atomic_min_f(float const* x, +__attribute__((always_inline)) INLINE void atomic_min_f(volatile float* x, float y) { - int done = 0; - while (!done) { - const float val = *x; - done = __sync_bool_compare_and_swap((int*)x, val, min(val, y)); - } + float test, new; + float old = *x; + do { + test = old; + new = min(old, y); + if (new == old) return; + old = atomic_cas((int*)x, test, new); + } while (test != old); } /** - * @param Atomic max operation on floats. + * @brief Atomic max operation on floats. */ -__attribute__((always_inline)) INLINE void atomic_max_f(float const* x, +__attribute__((always_inline)) INLINE void atomic_max_f(volatile float* x, float y) { - int done = 0; - while (!done) { - const float val = *x; - done = __sync_bool_compare_and_swap((int*)x, val, max(val, y)); - } + float test, new; + float old = *x; + do { + test = old; + new = max(old, y); + if (new == old) return; + old = atomic_cas((int*)x, test, new); + } while (test != old); } /** - * @param Atomic add operation on floats. + * @brief Atomic add operation on floats. */ -__attribute__((always_inline)) INLINE void atomic_add_f(float const* x, +__attribute__((always_inline)) INLINE void atomic_add_f(volatile float* x, float y) { - int done = 0; - while (!done) { - const float val = *x; - done = __sync_bool_compare_and_swap((int*)x, val, val + y); - } + float test, new; + float old = *x; + do { + test = old; + new = old + y; + if (new == old) return; + old = atomic_cas((int*)x, test, new); + } while (test != old); } #endif /* SWIFT_ATOMIC_H */ -- GitLab