00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef BASE_ATOMICOPS_INTERNALS_X86_MSVC_H__
00039 #define BASE_ATOMICOPS_INTERNALS_X86_MSVC_H__
00040 #include "base/basictypes.h"
00041
00042 typedef intptr_t AtomicWord;
00043 #ifdef _WIN64
00044 typedef LONG Atomic32;
00045 #else
00046 typedef AtomicWord Atomic32;
00047 #endif
00048
00049 COMPILE_ASSERT(sizeof(AtomicWord) == sizeof(PVOID), atomic_word_is_atomic);
00050
00051 inline AtomicWord CompareAndSwap(volatile AtomicWord* ptr,
00052 AtomicWord old_value,
00053 AtomicWord new_value) {
00054 PVOID result = InterlockedCompareExchangePointer(
00055 reinterpret_cast<volatile PVOID*>(ptr),
00056 reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value));
00057 return reinterpret_cast<AtomicWord>(result);
00058 }
00059
00060 inline AtomicWord AtomicExchange(volatile AtomicWord* ptr,
00061 AtomicWord new_value) {
00062 PVOID result = InterlockedExchangePointer(
00063 const_cast<PVOID*>(reinterpret_cast<volatile PVOID*>(ptr)),
00064 reinterpret_cast<PVOID>(new_value));
00065 return reinterpret_cast<AtomicWord>(result);
00066 }
00067
00068 #ifdef _WIN64
00069 inline Atomic32 AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment) {
00070
00071
00072
00073 return InterlockedExchangeAdd(ptr, increment) + increment;
00074 }
00075
00076 inline AtomicWord AtomicIncrement(volatile AtomicWord* ptr, AtomicWord increment) {
00077 return InterlockedExchangeAdd64(
00078 reinterpret_cast<volatile LONGLONG*>(ptr),
00079 static_cast<LONGLONG>(increment)) + increment;
00080 }
00081 #else
00082 inline AtomicWord AtomicIncrement(volatile AtomicWord* ptr, AtomicWord increment) {
00083 return InterlockedExchangeAdd(
00084 reinterpret_cast<volatile LONG*>(ptr),
00085 static_cast<LONG>(increment)) + increment;
00086 }
00087 #endif
00088
00089 inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
00090 AtomicWord old_value,
00091 AtomicWord new_value) {
00092 return CompareAndSwap(ptr, old_value, new_value);
00093 }
00094
00095 inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
00096 AtomicWord old_value,
00097 AtomicWord new_value) {
00098 return CompareAndSwap(ptr, old_value, new_value);
00099 }
00100
00101
00102 #if !(COMPILER_MSVC && _MSC_VER >= 1400)
00103 inline void MemoryBarrier() {
00104 AtomicWord value = 0;
00105 AtomicExchange(&value, 0);
00106 }
00107 #endif
00108
00109 inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
00110 AtomicExchange(ptr, value);
00111 }
00112
00113 inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
00114 *ptr = value;
00115
00116
00117
00118
00119
00120
00121
00122 }
00123
00124 inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
00125 AtomicWord value = *ptr;
00126 MemoryBarrier();
00127 return value;
00128 }
00129
00130 inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
00131 MemoryBarrier();
00132 return *ptr;
00133 }
00134
00135 #endif // BASE_ATOMICOPS_INTERNALS_X86_MSVC_H__