summaryrefslogtreecommitdiffstats
path: root/compat
diff options
context:
space:
mode:
Diffstat (limited to 'compat')
-rw-r--r--compat/atomics.h42
1 files changed, 36 insertions, 6 deletions
diff --git a/compat/atomics.h b/compat/atomics.h
index 14f0f2720f..56328ab354 100644
--- a/compat/atomics.h
+++ b/compat/atomics.h
@@ -16,17 +16,47 @@
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
-// At this point both gcc and clang had __sync_synchronize support for some
-// time. We only support a full memory barrier.
+#ifndef MP_ATOMICS_H
+#define MP_ATOMICS_H
+#include <inttypes.h>
#include "config.h"
+#if HAVE_STDATOMIC
+#include <stdatomic.h>
+#else
+
+// Emulate the parts of C11 stdatomic.h needed by mpv.
+// Still relies on gcc/clang atomic builtins.
+
+typedef struct { volatile unsigned long v; } atomic_ulong;
+typedef struct { volatile int v; } atomic_int;
+typedef struct { volatile _Bool v; } atomic_bool;
+typedef struct { volatile long long v; } atomic_llong;
+typedef struct { volatile uint_least32_t v; } atomic_uint_least32_t;
+typedef struct { volatile unsigned long long v; } atomic_ullong;
+
+#define ATOMIC_VAR_INIT(x) \
+ {.v = (x)}
+#define atomic_load(p) \
+ (mp_memory_barrier(), (p)->v)
+#define atomic_store(p, val) \
+ ((p)->v = (val), mp_memory_barrier())
+
#if HAVE_ATOMIC_BUILTINS
-# define mp_memory_barrier() __atomic_thread_fence(__ATOMIC_SEQ_CST)
-# define mp_atomic_add_and_fetch(a, b) __atomic_add_fetch(a, b,__ATOMIC_SEQ_CST)
+# define mp_memory_barrier() \
+ __atomic_thread_fence(__ATOMIC_SEQ_CST)
+# define atomic_fetch_add(a, b) \
+ __atomic_add_fetch(&(a)->v, b, __ATOMIC_SEQ_CST)
#elif HAVE_SYNC_BUILTINS
-# define mp_memory_barrier() __sync_synchronize()
-# define mp_atomic_add_and_fetch(a, b) __sync_add_and_fetch(a, b)
+# define mp_memory_barrier() \
+ __sync_synchronize()
+# define atomic_fetch_add(a, b) \
+ (__sync_add_and_fetch(&(a)->v, b), mp_memory_barrier())
#else
# error "this should have been a configuration error, report a bug please"
#endif
+
+#endif /* else HAVE_STDATOMIC */
+
+#endif