1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
From e31f85e6915d4bf6ed76c5da71c235525fa4ecc3 Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen.kooi@linaro.org>
Date: Mon, 14 Apr 2014 10:29:42 +0200
Subject: [PATCH 5/5] GCC 4.7+ supports atomic ops for armv5 and up, but only
exports the functions for armv6 and up. This patch works around the linker
problems associated with that.
Forward ported from http://pkgs.fedoraproject.org/cgit/mongodb.git/tree/mongodb-2.4.5-atomics.patch
Upstream-status: pending
---
src/mongo/bson/util/atomic_int.h | 26 ++++++++++++
src/mongo/platform/atomic_intrinsics_gcc_generic.h | 47 ++++++++++++++++++++++
2 files changed, 73 insertions(+)
diff --git a/src/mongo/bson/util/atomic_int.h b/src/mongo/bson/util/atomic_int.h
index 0b85363..ed02c23 100644
--- a/src/mongo/bson/util/atomic_int.h
+++ b/src/mongo/bson/util/atomic_int.h
@@ -24,6 +24,10 @@
#include "mongo/platform/compiler.h"
+#define GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
+
namespace mongo {
/**
@@ -72,6 +76,28 @@ namespace mongo {
InterlockedAdd((volatile long *)&x,by);
}
# endif
+#elif defined(GCC_VERSION) && GCC_VERSION >= 40700
+// in GCC version >= 4.7.0 we can use the built-in atomic operations
+
+ inline void AtomicUInt::set(unsigned newX) {
+ __atomic_store_n (&x, newX, __ATOMIC_SEQ_CST);
+ }
+ AtomicUInt AtomicUInt::operator++() { // ++prefix
+ return __atomic_add_fetch(&x, 1, __ATOMIC_SEQ_CST);
+ }
+ AtomicUInt AtomicUInt::operator++(int) { // postfix++
+ return __atomic_fetch_add(&x, 1, __ATOMIC_SEQ_CST);
+ }
+ AtomicUInt AtomicUInt::operator--() { // --prefix
+ return __atomic_add_fetch(&x, -1, __ATOMIC_SEQ_CST);
+ }
+ AtomicUInt AtomicUInt::operator--(int) { // postfix--
+ return __atomic_fetch_add(&x, -1, __ATOMIC_SEQ_CST);
+ }
+ void AtomicUInt::signedAdd(int by) {
+ __atomic_fetch_add(&x, by, __ATOMIC_SEQ_CST);
+ }
+
#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
// this is in GCC >= 4.1
inline void AtomicUInt::set(unsigned newX) { __sync_synchronize(); x = newX; }
diff --git a/src/mongo/platform/atomic_intrinsics_gcc_generic.h b/src/mongo/platform/atomic_intrinsics_gcc_generic.h
index 64a2499..b7cc176 100644
--- a/src/mongo/platform/atomic_intrinsics_gcc_generic.h
+++ b/src/mongo/platform/atomic_intrinsics_gcc_generic.h
@@ -22,8 +22,53 @@
#include <boost/utility.hpp>
+#define GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
+
namespace mongo {
+// If GCC version >= 4.7.0, we can use the built-in atomic operations
+#if defined(GCC_VERSION) && GCC_VERSION >= 40700
+
+ /**
+ * Instantiation of AtomicIntrinsics<>.
+ */
+ template <typename T>
+ class AtomicIntrinsics {
+ public:
+
+ static T compareAndSwap(volatile T* dest, T expected, T newValue) {
+ return __atomic_compare_exchange_n (dest, &expected, newValue, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+ }
+
+ static T swap(volatile T* dest, T newValue) {
+ return __atomic_exchange_n (dest, newValue, __ATOMIC_SEQ_CST);
+ }
+
+ static T load(volatile const T* value) {
+ return __atomic_load_n (value, __ATOMIC_SEQ_CST);
+ }
+
+ static T loadRelaxed(volatile const T* value) {
+ return *value;
+ }
+
+ static void store(volatile T* dest, T newValue) {
+ __atomic_store_n (dest, newValue, __ATOMIC_SEQ_CST);
+ }
+
+ static T fetchAndAdd(volatile T* dest, T increment) {
+ return __atomic_fetch_add (dest, increment, __ATOMIC_SEQ_CST);
+ }
+
+ private:
+ AtomicIntrinsics();
+ ~AtomicIntrinsics();
+ };
+
+#else // GCC version < 4.7, so we must use legacy (platform-specific) atomic operations
+
/**
* Instantiation of AtomicIntrinsics<> for all word types T.
*/
@@ -67,4 +112,6 @@ namespace mongo {
~AtomicIntrinsics();
};
+#endif // GCC_VERSION >= 40700
+
} // namespace mongo
--
1.9.0
|