summaryrefslogtreecommitdiff
path: root/SConstruct
diff options
context:
space:
mode:
authorAndrew Morrow <acm@mongodb.com>2014-05-16 14:51:48 -0400
committerAndrew Morrow <acm@mongodb.com>2014-05-17 15:46:28 -0400
commit3c202ac893db05e2486efd4a384c6bb49f01831f (patch)
treef7539949456bb9ad5bef9b5149ea366b639adee5 /SConstruct
parentab600c4056f13ee7dc49899bd76be4a8898b3360 (diff)
downloadmongo-3c202ac893db05e2486efd4a384c6bb49f01831f.tar.gz
SERVER-6018 SERVER-13913 Use std::atomic to implement AtomicWord in C++11 mode
Diffstat (limited to 'SConstruct')
-rw-r--r--SConstruct119
1 files changed, 75 insertions, 44 deletions
diff --git a/SConstruct b/SConstruct
index 06616dc1c54..09d7cb12276 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1429,54 +1429,86 @@ def doConfigure(myenv):
if haveUUThread:
myenv.Append(CPPDEFINES=['MONGO_HAVE___THREAD'])
- if using_gcc() or using_clang():
- def CheckGCCAtomicBuiltins(context):
- test_body = """
- int main(int argc, char **argv) {
- int a = 0;
- int b = 0;
- int c = 0;
+ def CheckCXX11Atomics(context):
+ test_body = """
+ #include <atomic>
+ int main(int argc, char **argv) {
+ std::atomic<int> a(0);
+ return a.fetch_add(1);
+ }
+ """
+ context.Message('Checking for C++11 <atomic> support... ')
+ ret = context.TryLink(textwrap.dedent(test_body), '.cpp')
+ context.Result(ret)
+ return ret;
- __atomic_compare_exchange(&a, &b, &c, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
- return 0;
- }
- """
- context.Message('Checking for gcc __atomic builtins... ')
- ret = context.TryLink(textwrap.dedent(test_body), '.cpp')
- context.Result(ret)
- return ret
+ def CheckGCCAtomicBuiltins(context):
+ test_body = """
+ int main(int argc, char **argv) {
+ int a = 0;
+ int b = 0;
+ int c = 0;
- def CheckGCCSyncBuiltins(context):
- test_body = """
- int main(int argc, char **argv) {
- int a = 0;
- return __sync_fetch_and_add(&a, 1);
- }
+ __atomic_compare_exchange(&a, &b, &c, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+ return 0;
+ }
+ """
+ context.Message('Checking for gcc __atomic builtins... ')
+ ret = context.TryLink(textwrap.dedent(test_body), '.cpp')
+ context.Result(ret)
+ return ret
- //
- // Figure out if we are using gcc older than 4.2 to target 32-bit x86. If so, error out
- // even if we were able to compile the __sync statement, due to
- // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40693
- //
- #if defined(__i386__)
- #if !defined(__clang__)
- #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 2)
- #error "Refusing to use __sync in 32-bit mode with gcc older than 4.2"
- #endif
- #endif
- #endif
- """
+ def CheckGCCSyncBuiltins(context):
+ test_body = """
+ int main(int argc, char **argv) {
+ int a = 0;
+ return __sync_fetch_and_add(&a, 1);
+ }
- context.Message('Checking for useable __sync builtins... ')
- ret = context.TryLink(textwrap.dedent(test_body), '.cpp')
- context.Result(ret)
- return ret
+ //
+ // Figure out if we are using gcc older than 4.2 to target 32-bit x86. If so, error out
+ // even if we were able to compile the __sync statement, due to
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40693
+ //
+ #if defined(__i386__)
+ #if !defined(__clang__)
+ #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 2)
+ #error "Refusing to use __sync in 32-bit mode with gcc older than 4.2"
+ #endif
+ #endif
+ #endif
+ """
- conf = Configure(myenv, help=False, custom_tests = {
- 'CheckGCCAtomicBuiltins': CheckGCCAtomicBuiltins,
- 'CheckGCCSyncBuiltins': CheckGCCSyncBuiltins,
- })
+ context.Message('Checking for useable __sync builtins... ')
+ ret = context.TryLink(textwrap.dedent(test_body), '.cpp')
+ context.Result(ret)
+ return ret
+
+ conf = Configure(myenv, help=False, custom_tests = {
+ 'CheckCXX11Atomics': CheckCXX11Atomics,
+ 'CheckGCCAtomicBuiltins': CheckGCCAtomicBuiltins,
+ 'CheckGCCSyncBuiltins': CheckGCCSyncBuiltins,
+ })
+ # Figure out what atomics mode to use by way of the tests defined above.
+ #
+ # Non_windows: <atomic> > __atomic > __sync
+ # Windows: <atomic> > Interlocked functions / intrinsics.
+ #
+ # If we are in C++11 mode, try to use <atomic>. This is unusual for us, as typically we
+ # only use __cplusplus >= 201103L to decide if we want to enable a feature. We make a
+ # special case for the atomics and use them on platforms that offer them even if they don't
+ # advertise full conformance. For MSVC systems, if we don't have <atomic> then no more
+ # checks are required. Otherwise, we are on a GCC/clang system, where we may have __atomic
+ # or __sync, so try those in that order next.
+ #
+ # If we don't end up defining a MONGO_HAVE for the atomics, we will end up falling back to
+ # the Microsoft Interlocked functions/intrinsics when using MSVC, or the gcc_intel
+ # implementation of hand-rolled assembly if using gcc/clang.
+
+ if (using_msvc() or (cxx11_mode == "on")) and conf.CheckCXX11Atomics():
+ conf.env.Append(CPPDEFINES=['MONGO_HAVE_CXX11_ATOMICS'])
+ elif using_gcc() or using_clang():
# Prefer the __atomic builtins. If we don't have those, try for __sync. Otherwise
# atomic_intrinsics.h will try to fall back to the hand-rolled assembly implementations
# in atomic_intrinsics_gcc_intel for x86 platforms.
@@ -1485,8 +1517,7 @@ def doConfigure(myenv):
else:
if conf.CheckGCCSyncBuiltins():
conf.env.Append(CPPDEFINES=["MONGO_HAVE_GCC_SYNC_BUILTINS"])
-
- myenv = conf.Finish()
+ myenv = conf.Finish()
conf = Configure(myenv)
libdeps.setup_conftests(conf)