changeset 27448:b47705865de7

fall back to system-dependent functions if compiling stdatomic.h fails * configure.ac: Check whether stdatomic.h can be compiled. * oct-atomic.c: Use system-dependent atomic increment and decrement functions if stdatomic.h can't be compiled.
author John W. Eaton <jwe@octave.org>
date Fri, 27 Sep 2019 15:59:53 -0400
parents 396996f1dad0
children 3cd724b25b3e
files configure.ac liboctave/util/oct-atomic.c
diffstat 2 files changed, 65 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Wed Sep 25 17:57:08 2019 -0400
+++ b/configure.ac	Fri Sep 27 15:59:53 2019 -0400
@@ -1085,6 +1085,24 @@
 AC_CHECK_HEADERS([dlfcn.h floatingpoint.h fpu_control.h grp.h])
 AC_CHECK_HEADERS([ieeefp.h pthread.h pwd.h sys/ioctl.h])
 
+## Some versions of GCC fail when using -fopenmp and including
+## stdatomic.h, so we try to work around that.  Use the compile_ifelse
+## macro because we are trying to test the case of the header file
+## existing but not being usable.  The default warning from the
+## check_headers macro is not appropriate here.
+AC_CACHE_CHECK([whether stdatomic.h can be compiled],
+  [octave_cv_stdatomic_h_ok],
+  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+    #include <stdatomic.h>
+    ]])],
+    octave_cv_stdatomic_h_ok=yes,
+    octave_cv_stdatomic_h_ok=no)
+  ])
+if test $octave_cv_stdatomic_h_ok = yes; then
+  AC_DEFINE(OCTAVE_STDATOMIC_H_OK, 1,
+    [Define to 1 if stdatomic.h can be compiled.])
+fi
+
 ## Find a termio header to include.
 
 AC_CHECK_HEADERS([termios.h], have_termios_h=yes, have_termios_h=no)
--- a/liboctave/util/oct-atomic.c	Wed Sep 25 17:57:08 2019 -0400
+++ b/liboctave/util/oct-atomic.c	Fri Sep 27 15:59:53 2019 -0400
@@ -26,7 +26,10 @@
 
 #include "oct-atomic.h"
 
-#include <stdatomic.h>
+/* Some versions of GCC can't compile stdatomic.h with -fopenmp.  */
+
+#if defined (OCTAVE_STDATOMIC_H_OK)
+#  include <stdatomic.h>
 
 octave_idx_type
 octave_atomic_increment (octave_idx_type *x)
@@ -43,3 +46,46 @@
 
   return *x;
 }
+
+#elif defined (__GNUC__)
+
+#warning "foobar"
+
+octave_idx_type
+octave_atomic_increment (octave_idx_type *x)
+{
+  return __sync_add_and_fetch (x,  1);
+}
+
+octave_idx_type
+octave_atomic_decrement (octave_idx_type *x)
+{
+  return __sync_sub_and_fetch (x, 1);
+}
+
+#elif defined (_MSC_VER)
+#  include <intrin.h>
+
+octave_idx_type
+octave_atomic_increment (octave_idx_type *x)
+{
+#if defined (OCTAVE_ENABLE_64)
+  return _InterlockedIncrement64 (x);
+#else
+  return _InterlockedIncrement (x);
+#endif
+}
+
+octave_idx_type
+octave_atomic_decrement (octave_idx_type *x)
+{
+#if defined (OCTAVE_ENABLE_64)
+  return _InterlockedDecrement64 (x);
+#else
+  return _InterlockedDecrement (x);
+#endif
+}
+
+#else
+#  error "Octave requires atomic integer increment and decrement functions"
+#endif