Mercurial > sdl-ios-xcode
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; |