00001 /* 00002 * Copyright 2006 Intel Corporation 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef __ATOMIC_WIN32_H__ 00018 #define __ATOMIC_WIN32_H__ 00019 00020 #include <Windows.h> 00021 00022 #include "../compat/inttypes.h" 00023 00024 struct atomic_t { 00025 atomic_t(LONG l = 0) : value(l) {} 00026 00027 volatile LONG value; 00028 }; 00029 00037 static inline void 00038 atomic_add(volatile atomic_t *v, int32_t i) 00039 { 00040 InterlockedExchangeAdd(&v->value, i); 00041 } 00042 00050 // static inline void 00051 // atomic_sub(volatile atomic_t* v, int32_t i) 00052 // { 00053 // __asm__ __volatile__( 00054 // LOCK "subl %1,%0" 00055 // :"=m" (v->value) 00056 // :"ir" (i), "m" (v->value)); 00057 // } 00058 00064 static inline void 00065 atomic_incr(volatile atomic_t* v) 00066 { 00067 InterlockedIncrement(&v->value); 00068 } 00069 00076 static inline void 00077 atomic_decr(volatile atomic_t* v) 00078 { 00079 InterlockedDecrement(&v->value); 00080 } 00081 00091 static inline bool 00092 atomic_decr_test(volatile atomic_t* v) 00093 { 00094 return 0 == InterlockedDecrement(&v->value); 00095 } 00096 00107 static inline int32_t 00108 atomic_cmpxchg32(volatile atomic_t* v, int32_t o, int32_t n) 00109 { 00110 return InterlockedCompareExchange(&v->value, 00111 static_cast<LONG>(n), 00112 static_cast<LONG>(o)); 00113 } 00114 00115 // /** 00116 // * Atomic increment function that returns the new value. Note that the 00117 // * implementation loops until it can successfully do the operation and 00118 // * store the value, so there is an extremely low chance that this will 00119 // * never return. 00120 // * 00121 // * @param v pointer to current value 00122 // */ 00123 // static inline int32_t 00124 // atomic_incr_ret(volatile atomic_t* v) 00125 // { 00126 // register volatile int32_t o, n; 00127 00128 // #if defined(NDEBUG) && NDEBUG == 1 00129 // while (1) 00130 // #else 00131 // register int j; 00132 // for (j = 0; j < 1000000; ++j) 00133 // #endif 00134 // { 00135 // o = v->value; 00136 // n = o + 1; 00137 // if (atomic_cmpxchg32(v, o, n) == o) 00138 // return n; 00139 // } 00140 00141 // NOTREACHED; 00142 // return 0; 00143 // } 00144 00145 // /** 00146 // * Atomic addition function that returns the new value. Note that the 00147 // * implementation loops until it can successfully do the operation and 00148 // * store the value, so there is an extremely low chance that this will 00149 // * never return. 00150 // * 00151 // * @param v pointer to current value 00152 // * @param i integer to add 00153 // */ 00154 // static inline int32_t 00155 // atomic_add_ret(volatile atomic_t* v, int32_t i) 00156 // { 00157 // register int32_t o, n; 00158 00159 // #if defined(NDEBUG) && NDEBUG == 1 00160 // while (1) 00161 // #else 00162 // register int j; 00163 // for (j = 0; j < 1000000; ++j) 00164 // #endif 00165 // { 00166 // o = v->value; 00167 // n = o + i; 00168 // if (atomic_cmpxchg32(v, o, n) == o) 00169 // return n; 00170 // } 00171 00172 // NOTREACHED; 00173 // return 0; 00174 // } 00175 00176 00177 #endif /* __ATOMIC_WIN32_H__ */