summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2018-06-21 14:17:35 +0200
committerRalph Boehme <slow@samba.org>2018-07-24 17:38:26 +0200
commit5fa5764f30c47b46f12ceb7637985e8def0190ca (patch)
treedd339ab817291e511076a07bf86d8e9f4ece65e0 /lib
parent6f8c1b6736875d63c11f8630ecf1c8d3dcd70fc5 (diff)
downloadsamba-5fa5764f30c47b46f12ceb7637985e8def0190ca.tar.gz
replace: add checks for atomic_thread_fence(memory_order_seq_cst) and add possible fallbacks
This implements a full memory barrier. On ubuntu amd64 with results in an 'mfence' instruction. This is required to syncronization between threads, where there's typically only one write of a memory that should be synced between all threads with the barrier. Much more details can be found here: https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/_005f_005fatomic-Builtins.html#g_t_005f_005fatomic-Builtins https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/_005f_005fsync-Builtins.html#g_t_005f_005fsync-Builtins The main one we use seems to be in C11 via stdatomic.h, the oldest fallback is __sync_synchronize(), which is available since 2005 in gcc. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/replace/system/threads.h27
-rw-r--r--lib/replace/wscript19
2 files changed, 45 insertions, 1 deletions
diff --git a/lib/replace/system/threads.h b/lib/replace/system/threads.h
index fe6d0fbac54..d189ed620c5 100644
--- a/lib/replace/system/threads.h
+++ b/lib/replace/system/threads.h
@@ -42,4 +42,31 @@
#define pthread_mutex_consistent pthread_mutex_consistent_np
#endif
+#ifdef HAVE_STDATOMIC_H
+#include <stdatomic.h>
+#endif
+
+#ifndef HAVE_ATOMIC_THREAD_FENCE
+#ifdef HAVE___ATOMIC_THREAD_FENCE
+#define atomic_thread_fence(__ignore_order) __atomic_thread_fence(__ATOMIC_SEQ_CST)
+#define HAVE_ATOMIC_THREAD_FENCE 1
+#endif /* HAVE___ATOMIC_THREAD_FENCE */
+#endif /* not HAVE_ATOMIC_THREAD_FENCE */
+
+#ifndef HAVE_ATOMIC_THREAD_FENCE
+#ifdef HAVE___SYNC_SYNCHRONIZE
+#define atomic_thread_fence(__ignore_order) __sync_synchronize()
+#define HAVE_ATOMIC_THREAD_FENCE 1
+#endif /* HAVE___SYNC_SYNCHRONIZE */
+#endif /* not HAVE_ATOMIC_THREAD_FENCE */
+
+#ifndef HAVE_ATOMIC_THREAD_FENCE
+#ifdef HAVE_ATOMIC_THREAD_FENCE_SUPPORT
+#error mismatch_error_between_configure_test_and_header
+#endif
+/* make sure the build fails if someone uses it without checking the define */
+#define atomic_thread_fence(__order) \
+ __function__atomic_thread_fence_not_available_on_this_platform__()
+#endif /* not HAVE_ATOMIC_THREAD_FENCE */
+
#endif
diff --git a/lib/replace/wscript b/lib/replace/wscript
index 02d98c59e47..5b53461f844 100644
--- a/lib/replace/wscript
+++ b/lib/replace/wscript
@@ -113,7 +113,7 @@ def configure(conf):
conf.CHECK_HEADERS('sys/extattr.h sys/ea.h sys/proplist.h sys/cdefs.h')
conf.CHECK_HEADERS('utmp.h utmpx.h lastlog.h')
conf.CHECK_HEADERS('syscall.h sys/syscall.h inttypes.h')
- conf.CHECK_HEADERS('sys/atomic.h')
+ conf.CHECK_HEADERS('sys/atomic.h stdatomic.h')
conf.CHECK_HEADERS('libgen.h')
if conf.CHECK_CFLAGS('-Wno-format-truncation'):
@@ -260,6 +260,23 @@ def configure(conf):
headers='stdint.h sys/atomic.h',
msg='Checking for atomic_add_32 compiler builtin')
+ # Check for thread fence. */
+ tf = conf.CHECK_CODE('atomic_thread_fence(memory_order_seq_cst);',
+ 'HAVE_ATOMIC_THREAD_FENCE',
+ headers='stdatomic.h',
+ msg='Checking for atomic_thread_fence(memory_order_seq_cst) in stdatomic.h')
+ if not tf:
+ tf = conf.CHECK_CODE('__atomic_thread_fence(__ATOMIC_SEQ_CST);',
+ 'HAVE___ATOMIC_THREAD_FENCE',
+ msg='Checking for __atomic_thread_fence(__ATOMIC_SEQ_CST)')
+ if not tf:
+ # __sync_synchronize() is available since 2005 in gcc.
+ tf = conf.CHECK_CODE('__sync_synchronize();',
+ 'HAVE___SYNC_SYNCHRONIZE',
+ msg='Checking for __sync_synchronize')
+ if tf:
+ conf.DEFINE('HAVE_ATOMIC_THREAD_FENCE_SUPPORT', 1)
+
conf.CHECK_CODE('''
#define FALL_THROUGH __attribute__((fallthrough))