diff options
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/platform/atomic_intrinsics.h | 10 | ||||
-rw-r--r-- | src/mongo/platform/atomic_intrinsics_gcc_atomic.h (renamed from src/mongo/platform/atomic_intrinsics_gcc_generic.h) | 2 | ||||
-rw-r--r-- | src/mongo/platform/atomic_intrinsics_gcc_sync.h | 110 | ||||
-rw-r--r-- | src/mongo/util/background.h | 1 | ||||
-rw-r--r-- | src/mongo/util/goodies.h | 1 |
5 files changed, 116 insertions, 8 deletions
diff --git a/src/mongo/platform/atomic_intrinsics.h b/src/mongo/platform/atomic_intrinsics.h index c67fa3495fb..d8a60ada361 100644 --- a/src/mongo/platform/atomic_intrinsics.h +++ b/src/mongo/platform/atomic_intrinsics.h @@ -54,14 +54,12 @@ #if defined(_WIN32) #include "mongo/platform/atomic_intrinsics_win32.h" -#elif defined(__GNUC__) -#if defined(HAVE_GCC_ATOMIC_BUILTINS) -#include "mongo/platform/atomic_intrinsics_gcc_generic.h" +#elif defined(MONGO_HAVE_GCC_ATOMIC_BUILTINS) +#include "mongo/platform/atomic_intrinsics_gcc_atomic.h" +#elif defined(MONGO_HAVE_GCC_SYNC_BUILTINS) +#include "mongo/platform/atomic_intrinsics_gcc_sync.h" #elif defined(__i386__) || defined(__x86_64__) #include "mongo/platform/atomic_intrinsics_gcc_intel.h" #else -#error "Unsupported platform: no gcc atomic builtins or port available" -#endif -#else #error "Unsupported os/compiler family" #endif diff --git a/src/mongo/platform/atomic_intrinsics_gcc_generic.h b/src/mongo/platform/atomic_intrinsics_gcc_atomic.h index 0848585d312..5e2e7d24a14 100644 --- a/src/mongo/platform/atomic_intrinsics_gcc_generic.h +++ b/src/mongo/platform/atomic_intrinsics_gcc_atomic.h @@ -32,8 +32,6 @@ #pragma once -#include <boost/utility.hpp> - namespace mongo { /** diff --git a/src/mongo/platform/atomic_intrinsics_gcc_sync.h b/src/mongo/platform/atomic_intrinsics_gcc_sync.h new file mode 100644 index 00000000000..2ff7b33f4be --- /dev/null +++ b/src/mongo/platform/atomic_intrinsics_gcc_sync.h @@ -0,0 +1,110 @@ +/* Copyright 2014 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Implementation of the AtomicIntrinsics<T>::* operations for systems on any + * architecture using a GCC 4.1+ compatible compiler toolchain. + */ + +#pragma once + +#include <boost/utility.hpp> + +namespace mongo { + + /** + * Instantiation of AtomicIntrinsics<> for all word types T. + */ + template <typename T, typename IsTLarge=void> + class AtomicIntrinsics { + public: + + static T compareAndSwap(volatile T* dest, T expected, T newValue) { + return __sync_val_compare_and_swap(dest, expected, newValue); + } + + static T swap(volatile T* dest, T newValue) { + T currentValue = *dest; + while (true) { + const T result = compareAndSwap(dest, currentValue, newValue); + if (result == currentValue) + return result; + currentValue = result; + } + } + + static T load(volatile const T* value) { + __sync_synchronize(); + T result = *value; + __sync_synchronize(); + return result; + } + + static T loadRelaxed(volatile const T* value) { + asm volatile("" ::: "memory"); + return *value; + } + + static void store(volatile T* dest, T newValue) { + __sync_synchronize(); + *dest = newValue; + __sync_synchronize(); + } + + static T fetchAndAdd(volatile T* dest, T increment) { + return __sync_fetch_and_add(dest, increment); + } + + private: + AtomicIntrinsics(); + ~AtomicIntrinsics(); + }; + + template <typename T> + class AtomicIntrinsics<T, typename boost::disable_if_c<sizeof(T) <= sizeof(void*)>::type> { + public: + + static T compareAndSwap(volatile T* dest, T expected, T newValue) { + return __sync_val_compare_and_swap(dest, expected, newValue); + } + + static T swap(volatile T* dest, T newValue) { + T currentValue = *dest; + while (true) { + const T result = compareAndSwap(dest, currentValue, newValue); + if (result == currentValue) + return result; + currentValue = result; + } + } + + static T load(volatile const T* value) { + return compareAndSwap(const_cast<volatile T*>(value), T(0), T(0)); + } + + static void store(volatile T* dest, T newValue) { + swap(dest, newValue); + } + + static T fetchAndAdd(volatile T* dest, T increment) { + return __sync_fetch_and_add(dest, increment); + } + + private: + AtomicIntrinsics(); + ~AtomicIntrinsics(); + }; + +} // namespace mongo diff --git a/src/mongo/util/background.h b/src/mongo/util/background.h index 855d09e56d2..23ec9fbd0f5 100644 --- a/src/mongo/util/background.h +++ b/src/mongo/util/background.h @@ -30,6 +30,7 @@ #pragma once #include <boost/scoped_ptr.hpp> +#include <boost/utility.hpp> #include <string> #include <vector> diff --git a/src/mongo/util/goodies.h b/src/mongo/util/goodies.h index a0275e11daa..3b69f5b278a 100644 --- a/src/mongo/util/goodies.h +++ b/src/mongo/util/goodies.h @@ -38,6 +38,7 @@ #include <boost/scoped_array.hpp> #include <boost/scoped_ptr.hpp> #include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> #include "mongo/bson/util/misc.h" |