build-sys: meson: Add atomic ops related checks
diff --git a/meson.build b/meson.build
index 7906b1d..4d5fc58 100644
--- a/meson.build
+++ b/meson.build
@@ -371,12 +371,23 @@
   endif
 endif
 
+# Atomic operations
+
+if get_option('atomic-arm-memory-barrier')
+    cdata.set('ATOMIC_ARM_MEMORY_BARRIER_ENABLED', 1)
+endif
+
+need_libatomic_ops = false
+
 atomictest = '''void func() {
   volatile int atomic = 2;
   __sync_bool_compare_and_swap (&atomic, 2, 3);
 }
 '''
+
 if cc.compiles(atomictest)
+  cdata.set('HAVE_ATOMIC_BUILTINS', 1)
+
   newatomictest = '''void func() {
     int c = 0;
     __atomic_store_n(&c, 4, __ATOMIC_SEQ_CST);
@@ -384,12 +395,48 @@
   '''
 
   if(cc.compiles(newatomictest))
-    cdata.set('HAVE_ATOMIC_BUILTINS_MEMORY_MODEL', true)
+    cdata.set('HAVE_ATOMIC_BUILTINS_MEMORY_MODEL', 1)
   endif
 
-  cdata.set('HAVE_ATOMIC_BUILTINS', true)
+elif host_machine.cpu_family() == 'arm'
+  if host_machine.system() == 'linux' and get_option('atomic-arm-linux-helpers')
+    cdata.set('ATOMIC_ARM_LINUX_HELPERS', 1)
+  else
+    armatomictest = '''void func() {
+      volatile int a=0;
+      int o=0, n=1, r;
+      asm volatile ("ldrex    %0, [%1]\n"
+      "subs  %0, %0, %2\n"
+      "strexeq %0, %3, [%1]\n"
+      : "=&r" (r)
+      : "r" (&a), "Ir" (o), "r" (n)
+      : "cc");
+      return (a==1 ? 0 : -1);
+    '''
+
+    if cc.compiles(aratomictest)
+      cdata.set('ATOMIC_ARM_INLINE_ASM', 1)
+    else
+      need_libatomic_ops = true
+    endif
+  endif # arm && !linux
+
+elif not ['freebsd', 'netbsd'].contains(host_machine.system())
+  need_libatomic_ops = true
+endif # !atomic helpers && !arm
+
+if need_libatomic_ops
+  assert(cc.has_header('atomic_ops.h'), 'Need libatomic_ops')
+
+  cdata.set('AO_REQUIRE_CAS', 1)
+
+  if host_machine.system() != 'windows'
+    libatomic_ops_dep = cc.find_library('atomic_ops', required : true)
+  else
+    libatomic_ops_dep = dependency('', required: false)
+  endif
 else
-  # FIXME: check if we need libatomic_ops
+  libatomic_ops_dep = dependency('', required: false)
 endif
 
 # FIXME: make sure it's >= 2.2
diff --git a/meson_options.txt b/meson_options.txt
index 09873dd..7668773 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -27,6 +27,12 @@
 option('running-from-build-tree',
        type : 'boolean',
        description : 'Enable running from build tree')
+option('atomic-arm-linux-helpers',
+       type : 'boolean', value : true,
+       description : 'Use inline asm or libatomic_ops instead')
+option('atomic-arm-memory-barrier',
+       type : 'boolean', value : false,
+       description : 'Enable memory barriers (only really needed in SMP arm systems)')
 
 # Paths
 
diff --git a/src/modules/alsa/meson.build b/src/modules/alsa/meson.build
index d8d46fa..5309dc1 100644
--- a/src/modules/alsa/meson.build
+++ b/src/modules/alsa/meson.build
@@ -32,7 +32,7 @@
   c_args : [pa_c_args, server_c_args],
   link_args : [nodelete_link_args],
   include_directories : [configinc, topinc],
-  dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, alsa_dep, dbus_dep, libm_dep, udev_dep],
+  dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, alsa_dep, dbus_dep, libatomic_ops_dep, libm_dep, udev_dep],
   install : true,
   install_rpath : privlibdir,
   install_dir : modlibexecdir,
diff --git a/src/modules/echo-cancel/meson.build b/src/modules/echo-cancel/meson.build
index cdb53d6..171a414 100644
--- a/src/modules/echo-cancel/meson.build
+++ b/src/modules/echo-cancel/meson.build
@@ -14,7 +14,7 @@
   libwebrtc_util_sources,
   cpp_args : [pa_c_args, server_c_args],
   include_directories : [configinc, topinc],
-  dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, webrtc_dep],
+  dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, libatomic_ops_dep, webrtc_dep],
   link_args : [nodelete_link_args, '-Wl,--unresolved-symbols=ignore-in-object-files'],
   install : true,
   install_rpath : privlibdir,
diff --git a/src/modules/rtp/meson.build b/src/modules/rtp/meson.build
index 29ab195..c3efde6 100644
--- a/src/modules/rtp/meson.build
+++ b/src/modules/rtp/meson.build
@@ -20,7 +20,7 @@
   c_args : [pa_c_args, server_c_args],
   link_args : [nodelete_link_args],
   include_directories : [configinc, topinc],
-  dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep],
+  dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, libatomic_ops_dep],
   install : true,
   install_rpath : privlibdir,
   install_dir : modlibexecdir,
diff --git a/src/pulsecore/meson.build b/src/pulsecore/meson.build
index b595e77..19f6b9e 100644
--- a/src/pulsecore/meson.build
+++ b/src/pulsecore/meson.build
@@ -198,7 +198,7 @@
   install_rpath : privlibdir,
   install_dir : privlibdir,
   link_with : libpulsecore_simd_lib,
-  dependencies : [libm_dep, libpulsecommon_dep, libpulse_dep, ltdl_dep, shm_dep, sndfile_dep, database_dep, dbus_dep, orc_dep, samplerate_dep, soxr_dep, speex_dep, x11_dep],
+  dependencies : [libm_dep, libpulsecommon_dep, libpulse_dep, ltdl_dep, shm_dep, sndfile_dep, database_dep, dbus_dep, libatomic_ops_dep, orc_dep, samplerate_dep, soxr_dep, speex_dep, x11_dep],
   implicit_include_directories : false)
 
 libpulsecore_dep = declare_dependency(link_with: libpulsecore)
diff --git a/src/tests/meson.build b/src/tests/meson.build
index 15286f5..d68fbd0 100644
--- a/src/tests/meson.build
+++ b/src/tests/meson.build
@@ -82,7 +82,7 @@
 if host_machine.system() != 'darwin'
   default_tests += [
     [ 'once-test', 'once-test.c',
-      [ check_dep, thread_dep, libpulse_dep, libpulsecommon_dep, libpulsecore_dep ] ],
+      [ check_dep, thread_dep, libpulse_dep, libpulsecommon_dep, libpulsecore_dep, libatomic_ops_dep ] ],
   ]
 endif