Skip to content
Snippets Groups Projects
Commit 3379d0e8 authored by Matthieu Schaller's avatar Matthieu Schaller
Browse files

Cleaner implementation of the atomic operations for floats.

parent 68c5af52
No related branches found
No related tags found
No related merge requests found
...@@ -36,44 +36,86 @@ ...@@ -36,44 +36,86 @@
/** /**
* @brief Atomic min operation on floats. * @brief Atomic min operation on floats.
*
* This is a text-book implementation based on an atomic CAS.
*
* @param address The address to update.
* @param y The value to update the address with.
*/ */
__attribute__((always_inline)) INLINE static void atomic_min_f( __attribute__((always_inline)) INLINE static void atomic_min_f(
volatile float* x, float y) { volatile float* address, float y) {
float test, new;
float old = *x; int* int_ptr = (int*)address;
typedef union {
float as_float;
int as_int;
} cast_type;
cast_type assumed, old, new;
old.as_float = *address;
do { do {
test = old; assumed.as_int = old.as_int;
new = min(old, y); new.as_float = min(old.as_float, y);
old = atomic_cas((int*)x, test, new); old.as_int = atomic_cas(int_ptr, assumed.as_int, new.as_int);
} while (test != old); } while (assumed.as_int != old.as_int);
} }
/** /**
* @brief Atomic max operation on floats. * @brief Atomic max operation on floats.
*
* This is a text-book implementation based on an atomic CAS.
*
* @param address The address to update.
* @param y The value to update the address with.
*/ */
__attribute__((always_inline)) INLINE static void atomic_max_f( __attribute__((always_inline)) INLINE static void atomic_max_f(
volatile float* x, float y) { volatile float* address, float y) {
float test, new;
float old = *x; int* int_ptr = (int*)address;
typedef union {
float as_float;
int as_int;
} cast_type;
cast_type assumed, old, new;
old.as_float = *address;
do { do {
test = old; assumed.as_int = old.as_int;
new = max(old, y); new.as_float = max(old.as_float, y);
old = atomic_cas((int*)x, test, new); old.as_int = atomic_cas(int_ptr, assumed.as_int, new.as_int);
} while (test != old); } while (assumed.as_int != old.as_int);
} }
/** /**
* @brief Atomic add operation on floats. * @brief Atomic add operation on floats.
*
* This is a text-book implementation based on an atomic CAS.
*
* @param address The address to update.
* @param y The value to update the address with.
*/ */
__attribute__((always_inline)) INLINE static void atomic_add_f( __attribute__((always_inline)) INLINE static void atomic_add_f(
volatile float* x, float y) { volatile float* address, float y) {
float test, new;
float old = *x; int* int_ptr = (int*)address;
typedef union {
float as_float;
int as_int;
} cast_type;
cast_type assumed, old, new;
old.as_float = *address;
do { do {
test = old; assumed.as_int = old.as_int;
new = old + y; new.as_float = old.as_float + y;
old = atomic_cas((int*)x, test, new); old.as_int = atomic_cas(int_ptr, assumed.as_int, new.as_int);
} while (test != old); } while (assumed.as_int != old.as_int);
} }
#endif /* SWIFT_ATOMIC_H */ #endif /* SWIFT_ATOMIC_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment