comparison src/atomic/win32/SDL_atomic.c @ 3306:a8ec88ff18c7

This version actaully should work on Windows.
author Bob Pendleton <bob@pendleton.com>
date Fri, 25 Sep 2009 19:17:16 +0000
parents 72b542f34739
children 0e000afe3dc0
comparison
equal deleted inserted replaced
3305:bd88e323ad02 3306:a8ec88ff18c7
24 24
25 #include "SDL_stdinc.h" 25 #include "SDL_stdinc.h"
26 #include "SDL_atomic.h" 26 #include "SDL_atomic.h"
27 27
28 #include "SDL_error.h" 28 #include "SDL_error.h"
29 #include "Windows.h"
29 30
30 /* 31 /*
31 This file provides 32, and 64 bit atomic operations. If the 32 This file provides 32, and 64 bit atomic operations. If the
32 operations are provided by the native hardware and operating system 33 operations are provided by the native hardware and operating system
33 they are used. If they are not then the operations are emulated 34 they are used. If they are not then the operations are emulated
34 using the SDL spin lock operations. If spin lock can not be 35 using the SDL spin lock operations. If spin lock can not be
35 implemented then these functions must fail. 36 implemented then these functions must fail.
36 */ 37 */
37 38
38 /* 39 /*
39 DUMMY VERSION. 40 WIN32 VERSION.
40 41
41 This version of the code assumes there is no support for atomic 42 This makes use of native Windows atomic operations.
42 operations. Therefore, every function sets the SDL error
43 message. Oddly enough, if you only have one thread then this
44 version actuallys works.
45 */ 43 */
46 44
47 /* 45 /*
48 Native spinlock routines. Because this is the dummy implementation 46 Native spinlock routines. Because this is the dummy implementation
49 these will always call SDL_SetError() and do nothing. 47 these will always call SDL_SetError() and do nothing.
50 */ 48 */
51 49
52 void 50 void
53 SDL_AtomicLock(SDL_SpinLock *lock) 51 SDL_AtomicLock(SDL_SpinLock *lock)
54 { 52 {
55 SDL_SetError("SDL_atomic.c: is not implemented on this platform"); 53 long volatile * l = (long volatile *)lock;
54 Uint32 old = 0;
55 Uint32 new = 1;
56
57 old = InterlockedExchange(l, new);
58 while(1 == old)
59 {
60 old = InterlockedExchange(l, new);
61 }
56 } 62 }
57 63
58 void 64 void
59 SDL_AtomicUnlock(SDL_SpinLock *lock) 65 SDL_AtomicUnlock(SDL_SpinLock *lock)
60 { 66 {
61 SDL_SetError("SDL_atomic.c: is not implemented on this platform"); 67 long volatile * l = (long volatile *)lock;
68 Uint32 new = 0;
69
70 InterlockedExchange(l, new);
62 } 71 }
63 72
64 /* 73 /*
65 Note that platform specific versions can be built from this version 74 Note that platform specific versions can be built from this version
66 by changing the #undefs to #defines and adding platform specific 75 by changing the #undefs to #defines and adding platform specific
67 code. 76 code.
68 */ 77 */
69 78
70 #undef nativeTestThenSet32 79 #define nativeTestThenSet32
71 #undef nativeClear32 80 #define nativeClear32
72 #undef nativeFetchThenIncrement32 81 #define nativeFetchThenIncrement32
73 #undef nativeFetchThenDecrement32 82 #define nativeFetchThenDecrement32
74 #undef nativeFetchThenAdd32 83 #define nativeFetchThenAdd32
75 #undef nativeFetchThenSubtract32 84 #define nativeFetchThenSubtract32
76 #undef nativeIncrementThenFetch32 85 #define nativeIncrementThenFetch32
77 #undef nativeDecrementThenFetch32 86 #define nativeDecrementThenFetch32
78 #undef nativeAddThenFetch32 87 #define nativeAddThenFetch32
79 #undef nativeSubtractThenFetch32 88 #define nativeSubtractThenFetch32
80 89
81 #undef nativeTestThenSet64 90 #undef nativeTestThenSet64
82 #undef nativeClear64 91 #undef nativeClear64
83 #undef nativeFetchThenIncrement64 92 #undef nativeFetchThenIncrement64
84 #undef nativeFetchThenDecrement64 93 #undef nativeFetchThenDecrement64
145 154
146 SDL_bool 155 SDL_bool
147 SDL_AtomicTestThenSet32(volatile Uint32 * ptr) 156 SDL_AtomicTestThenSet32(volatile Uint32 * ptr)
148 { 157 {
149 #ifdef nativeTestThenSet32 158 #ifdef nativeTestThenSet32
159 long volatile * p = (long volatile *)ptr;
160 Uint32 new = 1;
161
162 return 0 == InterlockedExchange(p, new);
150 #else 163 #else
151 SDL_bool result = SDL_FALSE; 164 SDL_bool result = SDL_FALSE;
152 165
153 privateWaitLock(ptr); 166 privateWaitLock(ptr);
154 result = (*ptr == 0); 167 result = (*ptr == 0);
164 177
165 void 178 void
166 SDL_AtomicClear32(volatile Uint32 * ptr) 179 SDL_AtomicClear32(volatile Uint32 * ptr)
167 { 180 {
168 #ifdef nativeClear32 181 #ifdef nativeClear32
182 long volatile * p = (long volatile *)ptr;
183 Uint32 new = 0;
184
185 InterlockedExchange(p, new);
169 #else 186 #else
170 privateWaitLock(ptr); 187 privateWaitLock(ptr);
171 *ptr = 0; 188 *ptr = 0;
172 privateUnlock(ptr); 189 privateUnlock(ptr);
173 190
177 194
178 Uint32 195 Uint32
179 SDL_AtomicFetchThenIncrement32(volatile Uint32 * ptr) 196 SDL_AtomicFetchThenIncrement32(volatile Uint32 * ptr)
180 { 197 {
181 #ifdef nativeFetchThenIncrement32 198 #ifdef nativeFetchThenIncrement32
199 long volatile * p = (long volatile *)ptr;
200
201 return InterlockedExchangeAdd(p, 1);
182 #else 202 #else
183 Uint32 tmp = 0; 203 Uint32 tmp = 0;
184 204
185 privateWaitLock(ptr); 205 privateWaitLock(ptr);
186 tmp = *ptr; 206 tmp = *ptr;
193 213
194 Uint32 214 Uint32
195 SDL_AtomicFetchThenDecrement32(volatile Uint32 * ptr) 215 SDL_AtomicFetchThenDecrement32(volatile Uint32 * ptr)
196 { 216 {
197 #ifdef nativeFetchThenDecrement32 217 #ifdef nativeFetchThenDecrement32
218 long volatile * p = (long volatile *)ptr;
219
220 return InterlockedExchangeAdd(p, -1);
198 #else 221 #else
199 Uint32 tmp = 0; 222 Uint32 tmp = 0;
200 223
201 privateWaitLock(ptr); 224 privateWaitLock(ptr);
202 tmp = *ptr; 225 tmp = *ptr;
209 232
210 Uint32 233 Uint32
211 SDL_AtomicFetchThenAdd32(volatile Uint32 * ptr, Uint32 value) 234 SDL_AtomicFetchThenAdd32(volatile Uint32 * ptr, Uint32 value)
212 { 235 {
213 #ifdef nativeFetchThenAdd32 236 #ifdef nativeFetchThenAdd32
237 long volatile * p = (long volatile *)ptr;
238
239 return InterlockedExchangeAdd(p, value);
214 #else 240 #else
215 Uint32 tmp = 0; 241 Uint32 tmp = 0;
216 242
217 privateWaitLock(ptr); 243 privateWaitLock(ptr);
218 tmp = *ptr; 244 tmp = *ptr;
225 251
226 Uint32 252 Uint32
227 SDL_AtomicFetchThenSubtract32(volatile Uint32 * ptr, Uint32 value) 253 SDL_AtomicFetchThenSubtract32(volatile Uint32 * ptr, Uint32 value)
228 { 254 {
229 #ifdef nativeFetchThenSubtract32 255 #ifdef nativeFetchThenSubtract32
256 long volatile * p = (long volatile *)ptr;
257
258 return InterlockedExchangeAdd(p, (0 - value));
230 #else 259 #else
231 Uint32 tmp = 0; 260 Uint32 tmp = 0;
232 261
233 privateWaitLock(ptr); 262 privateWaitLock(ptr);
234 tmp = *ptr; 263 tmp = *ptr;
241 270
242 Uint32 271 Uint32
243 SDL_AtomicIncrementThenFetch32(volatile Uint32 * ptr) 272 SDL_AtomicIncrementThenFetch32(volatile Uint32 * ptr)
244 { 273 {
245 #ifdef nativeIncrementThenFetch32 274 #ifdef nativeIncrementThenFetch32
275 long volatile * p = (LONG volatile *)ptr;
276
277 return InterlockedIncrement(p);
246 #else 278 #else
247 Uint32 tmp = 0; 279 Uint32 tmp = 0;
248 280
249 privateWaitLock(ptr); 281 privateWaitLock(ptr);
250 (*ptr)+= 1; 282 (*ptr)+= 1;
257 289
258 Uint32 290 Uint32
259 SDL_AtomicDecrementThenFetch32(volatile Uint32 * ptr) 291 SDL_AtomicDecrementThenFetch32(volatile Uint32 * ptr)
260 { 292 {
261 #ifdef nativeDecrementThenFetch32 293 #ifdef nativeDecrementThenFetch32
294 long volatile * p = (LONG volatile *)ptr;
295
296 return InterlockedDecrement(p);
262 #else 297 #else
263 Uint32 tmp = 0; 298 Uint32 tmp = 0;
264 299
265 privateWaitLock(ptr); 300 privateWaitLock(ptr);
266 (*ptr)-= 1; 301 (*ptr)-= 1;
273 308
274 Uint32 309 Uint32
275 SDL_AtomicAddThenFetch32(volatile Uint32 * ptr, Uint32 value) 310 SDL_AtomicAddThenFetch32(volatile Uint32 * ptr, Uint32 value)
276 { 311 {
277 #ifdef nativeAddThenFetch32 312 #ifdef nativeAddThenFetch32
313 long volatile * p = (long volatile *)ptr;
314
315 return InterlockedExchangeAdd(p, value) + value;
278 #else 316 #else
279 Uint32 tmp = 0; 317 Uint32 tmp = 0;
280 318
281 privateWaitLock(ptr); 319 privateWaitLock(ptr);
282 (*ptr)+= value; 320 (*ptr)+= value;
289 327
290 Uint32 328 Uint32
291 SDL_AtomicSubtractThenFetch32(volatile Uint32 * ptr, Uint32 value) 329 SDL_AtomicSubtractThenFetch32(volatile Uint32 * ptr, Uint32 value)
292 { 330 {
293 #ifdef nativeSubtractThenFetch32 331 #ifdef nativeSubtractThenFetch32
332 long volatile * p = (long volatile *)ptr;
333
334 return InterlockedExchangeAdd(p, (0 - value)) - value;
294 #else 335 #else
295 Uint32 tmp = 0; 336 Uint32 tmp = 0;
296 337
297 privateWaitLock(ptr); 338 privateWaitLock(ptr);
298 (*ptr)-= value; 339 (*ptr)-= value;