diff options
author | Andy Schwerin <schwerin@10gen.com> | 2012-04-11 16:05:01 -0400 |
---|---|---|
committer | Andy Schwerin <schwerin@10gen.com> | 2012-04-12 13:36:51 -0400 |
commit | 7cb696d7761b56ac87e70f140bb351478e5a5898 (patch) | |
tree | 80dea3e3754bb5cac67e07b6d350c7b1b759b1b4 /src/mongo/bson | |
parent | 330f8820c636e18d8166f78db74f8d66129832e0 (diff) | |
download | mongo-7cb696d7761b56ac87e70f140bb351478e5a5898.tar.gz |
Some fix-up of the 32-bit AtomicUint type.
Diffstat (limited to 'src/mongo/bson')
-rw-r--r-- | src/mongo/bson/util/atomic_int.h | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/mongo/bson/util/atomic_int.h b/src/mongo/bson/util/atomic_int.h index d3c2bb7e19c..14af368ac58 100644 --- a/src/mongo/bson/util/atomic_int.h +++ b/src/mongo/bson/util/atomic_int.h @@ -22,28 +22,38 @@ # include <windows.h> #endif +#include "mongo/platform/compiler.h" + namespace mongo { - struct AtomicUInt { + /** + * An unsigned integer supporting atomic read-modify-write operations. + * + * Many operations on these types depend on natural alignment (4 byte alignment for 4-byte + * words, i.e.). + */ + struct MONGO_COMPILER_ALIGN_TYPE( 4 ) AtomicUInt { AtomicUInt() : x(0) {} AtomicUInt(unsigned z) : x(z) { } operator unsigned() const { return x; } unsigned get() const { return x; } + inline void set(unsigned newX); inline AtomicUInt operator++(); // ++prefix inline AtomicUInt operator++(int);// postfix++ inline AtomicUInt operator--(); // --prefix inline AtomicUInt operator--(int); // postfix-- inline void signedAdd(int by); - inline void zero(); + inline void zero() { set(0); } volatile unsigned x; }; #if defined(_WIN32) - void AtomicUInt::zero() { - InterlockedExchange((volatile long*)&x, 0); + void AtomicUInt::set(unsigned newX) { + InterlockedExchange((volatile long *)&x, newX); } + AtomicUInt AtomicUInt::operator++() { return InterlockedIncrement((volatile long*)&x); } @@ -64,7 +74,7 @@ namespace mongo { # endif #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) // this is in GCC >= 4.1 - inline void AtomicUInt::zero() { x = 0; } // TODO: this isn't thread safe - maybe + inline void AtomicUInt::set(unsigned newX) { __sync_synchronize(); x = newX; } AtomicUInt AtomicUInt::operator++() { return __sync_add_and_fetch(&x, 1); } @@ -81,7 +91,11 @@ namespace mongo { __sync_fetch_and_add(&x, by); } #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - inline void AtomicUInt::zero() { x = 0; } // TODO: this isn't thread safe + inline void AtomicUInt::set(unsigned newX) { + asm volatile("mfence" ::: "memory"); + x = 0; + } + // from boost 1.39 interprocess/detail/atomic.hpp inline unsigned atomic_int_helper(volatile unsigned *x, int val) { int r; |