diff options
Diffstat (limited to 'osdep/atomics.h')
-rw-r--r-- | osdep/atomics.h | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/osdep/atomics.h b/osdep/atomics.h index bfcaa38977..1d5134f646 100644 --- a/osdep/atomics.h +++ b/osdep/atomics.h @@ -80,6 +80,49 @@ typedef struct { volatile unsigned long long v; } atomic_ullong; if (!ok_) *(old) = val_; \ ok_; }) +#elif defined(__GNUC__) + +#include <pthread.h> + +extern pthread_mutex_t mp_atomic_mutex; + +#define atomic_load(p) \ + ({ __typeof__(p) p_ = (p); \ + pthread_mutex_lock(&mp_atomic_mutex); \ + __typeof__(p_->v) v = p_->v; \ + pthread_mutex_unlock(&mp_atomic_mutex); \ + v; }) +#define atomic_store(p, val) \ + ({ __typeof__(val) val_ = (val); \ + __typeof__(p) p_ = (p); \ + pthread_mutex_lock(&mp_atomic_mutex); \ + p_->v = val_; \ + pthread_mutex_unlock(&mp_atomic_mutex); }) +#define atomic_fetch_op(a, b, op) \ + ({ __typeof__(a) a_ = (a); \ + __typeof__(b) b_ = (b); \ + pthread_mutex_lock(&mp_atomic_mutex); \ + __typeof__(a_->v) v = a_->v; \ + a_->v = v op b_; \ + pthread_mutex_unlock(&mp_atomic_mutex); \ + v; }) +#define atomic_fetch_add(a, b) atomic_fetch_op(a, b, +) +#define atomic_fetch_and(a, b) atomic_fetch_op(a, b, &) +#define atomic_fetch_or(a, b) atomic_fetch_op(a, b, |) +#define atomic_compare_exchange_strong(p, old, new) \ + ({ __typeof__(p) p_ = (p); \ + __typeof__(old) old_ = (old); \ + __typeof__(new) new_ = (new); \ + pthread_mutex_lock(&mp_atomic_mutex); \ + int res = p_->v == *old_; \ + if (res) { \ + p_->v = new_; \ + } else { \ + *old_ = p_->v; \ + } \ + pthread_mutex_unlock(&mp_atomic_mutex); \ + res; }) + #else # error "this should have been a configuration error, report a bug please" #endif /* no atomics */ |