summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--osdep/atomics.h43
-rw-r--r--player/main.c4
-rw-r--r--wscript8
3 files changed, 53 insertions, 2 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 */
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
@@ -149,6 +149,10 @@ main_dependencies = [
'req': True,
'fmsg': 'Unable to find pthreads support.'
}, {
+ 'name': 'gnuc',
+ 'desc': 'GNU C extensions',
+ 'func': check_statement([], "__GNUC__"),
+ }, {
'name': 'stdatomic',
'desc': 'stdatomic.h',
'func': check_libs(['atomic'],
@@ -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',