00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #pragma once
00020
00021 #if defined(_WIN32)
00022 # include <windows.h>
00023 #endif
00024
00025 namespace mongo {
00026
00027 struct AtomicUInt {
00028 AtomicUInt() : x(0) {}
00029 AtomicUInt(unsigned z) : x(z) { }
00030
00031 operator unsigned() const { return x; }
00032 unsigned get() const { return x; }
00033
00034 inline AtomicUInt operator++();
00035 inline AtomicUInt operator++(int);
00036 inline AtomicUInt operator--();
00037 inline AtomicUInt operator--(int);
00038
00039 inline void zero() { x = 0; }
00040
00041 volatile unsigned x;
00042 };
00043
00044 #if defined(_WIN32)
00045 AtomicUInt AtomicUInt::operator++() {
00046
00047 return InterlockedIncrement((volatile long*)&x);
00048 }
00049 AtomicUInt AtomicUInt::operator++(int) {
00050 return InterlockedIncrement((volatile long*)&x)-1;
00051 }
00052 AtomicUInt AtomicUInt::operator--() {
00053 return InterlockedDecrement((volatile long*)&x);
00054 }
00055 AtomicUInt AtomicUInt::operator--(int) {
00056 return InterlockedDecrement((volatile long*)&x)+1;
00057 }
00058 #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
00059
00060 AtomicUInt AtomicUInt::operator++() {
00061 return __sync_add_and_fetch(&x, 1);
00062 }
00063 AtomicUInt AtomicUInt::operator++(int) {
00064 return __sync_fetch_and_add(&x, 1);
00065 }
00066 AtomicUInt AtomicUInt::operator--() {
00067 return __sync_add_and_fetch(&x, -1);
00068 }
00069 AtomicUInt AtomicUInt::operator--(int) {
00070 return __sync_fetch_and_add(&x, -1);
00071 }
00072 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
00073
00074
00075 inline unsigned atomic_int_helper(volatile unsigned *x, int val) {
00076 int r;
00077 asm volatile
00078 (
00079 "lock\n\t"
00080 "xadd %1, %0":
00081 "+m"( *x ), "=r"( r ):
00082 "1"( val ):
00083 "memory", "cc"
00084 );
00085 return r;
00086 }
00087 AtomicUInt AtomicUInt::operator++() {
00088 return atomic_int_helper(&x, 1)+1;
00089 }
00090 AtomicUInt AtomicUInt::operator++(int) {
00091 return atomic_int_helper(&x, 1);
00092 }
00093 AtomicUInt AtomicUInt::operator--() {
00094 return atomic_int_helper(&x, -1)-1;
00095 }
00096 AtomicUInt AtomicUInt::operator--(int) {
00097 return atomic_int_helper(&x, -1);
00098 }
00099 #else
00100 # error "unsupported compiler or platform"
00101 #endif
00102
00103 }