diff options
author | Mathias Stearn <mathias@10gen.com> | 2009-12-02 12:17:47 -0500 |
---|---|---|
committer | Mathias Stearn <mathias@10gen.com> | 2009-12-02 12:17:47 -0500 |
commit | f5c9a86b92343fd718129e6caceefc67e00a0ff5 (patch) | |
tree | 0ab96adc99e175b63006261314e35126b7905aba | |
parent | c0e79bf1d4b6a2813a0aa93bc63fdb6c89c281c0 (diff) | |
download | mongo-f5c9a86b92343fd718129e6caceefc67e00a0ff5.tar.gz |
Atomic increment (try 3)
-rw-r--r-- | util/goodies.h | 29 |
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) { |