summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2009-12-02 12:17:47 -0500
committerMathias Stearn <mathias@10gen.com>2009-12-02 12:17:47 -0500
commitf5c9a86b92343fd718129e6caceefc67e00a0ff5 (patch)
tree0ab96adc99e175b63006261314e35126b7905aba
parentc0e79bf1d4b6a2813a0aa93bc63fdb6c89c281c0 (diff)
downloadmongo-f5c9a86b92343fd718129e6caceefc67e00a0ff5.tar.gz
Atomic increment (try 3)
-rw-r--r--util/goodies.h29
1 files changed, 27 insertions, 2 deletions
diff --git a/util/goodies.h b/util/goodies.h
index 3d34715a430..21ade5f85b8 100644
--- a/util/goodies.h
+++ b/util/goodies.h
@@ -19,6 +19,10 @@
#pragma once
+#if defined(__MSCV__)
+# include <windows.h>
+#endif
+
namespace mongo {
#if !defined(_WIN32) && !defined(NOEXECINFO)
@@ -117,9 +121,30 @@ namespace mongo {
return x;
}
- // TODO: make atomic
+ // returns original value (like x++)
WrappingInt atomicIncrement(){
- return x++;
+#if defined(__MSCV__)
+ // InterlockedIncrement returns the new value
+ return InterlockedIncrement((volatile long*)&x)-1; //long is 32bits in Win64
+#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+ // this is in GCC >= 4.1
+ return __sync_fetch_and_add(&x, 1);
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+ // from boost 1.39 interprocess/detail/atomic.hpp
+ int r;
+ int val = 1;
+ asm volatile
+ (
+ "lock\n\t"
+ "xadd %1, %0":
+ "+m"( x ), "=r"( r ): // outputs (%0, %1)
+ "1"( val ): // inputs (%2 == %1)
+ "memory", "cc" // clobbers
+ );
+ return r;
+#else
+# error "unsupported compiler or platform"
+#endif
}
static int diff(unsigned a, unsigned b) {