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 + +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 */ diff --git a/player/main.c b/player/main.c index 0bf207f5b7..b1aa30f9c3 100644 --- a/player/main.c +++ b/player/main.c @@ -75,6 +75,10 @@ #define FULLCONFIG "(missing)\n" #endif +#if !(HAVE_STDATOMIC || HAVE_ATOMIC_BUILTINS || HAVE_SYNC_BUILTINS) +pthread_mutex_t mp_atomic_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + enum exit_reason { EXIT_NONE, EXIT_NORMAL, diff --git a/wscript b/wscript index 5553b23c72..7eed072bb6 100644 --- a/wscript +++ b/wscript @@ -148,6 +148,10 @@ main_dependencies = [ 'func': check_pthreads, 'req': True, 'fmsg': 'Unable to find pthreads support.' + }, { + 'name': 'gnuc', + 'desc': 'GNU C extensions', + 'func': check_statement([], "__GNUC__"), }, { 'name': 'stdatomic', 'desc': 'stdatomic.h', @@ -173,10 +177,10 @@ main_dependencies = [ 'deps_neg': [ 'stdatomic', 'atomic-builtins' ], }, { 'name': 'atomics', - 'desc': 'compiler support for usable thread synchronization built-ins', + 'desc': 'stdatomic.h support or emulation', 'func': check_true, 'req': True, - 'deps_any': ['stdatomic', 'atomic-builtins', 'sync-builtins'], + 'deps_any': ['stdatomic', 'atomic-builtins', 'sync-builtins', 'gnuc'], }, { 'name': 'c11-tls', 'desc': 'C11 TLS support',