Mercurial > sdl-ios-xcode
comparison src/atomic/dummy/SDL_atomic.c @ 3202:3aa519a5c676
I've made so many changes I don't dare continue until I check the current stuff in.
/test/testatomic.c performs absolutely basic tests to show that the function work as expected. Need a second test to do more detailed tests.
/include/SDL_atomic.h provides declarations for all included functions.
/src/atomic/linux/SDL_atomic.c provided all the functions. On a generic built the 64 bit functions work, but they are emulated. On a build for -march=pentium and above the 64 bit functions use native instructions
/src/atomic/dummy/SDL_atomic.c emulates all the operations using SDL_mutex.h.
/src/atomic/win32/SDL_atomic.c is a copy of dummy
/src/atomic/macosx/SDL_atomic.s is a copy of dummy
These versions of SDL_atomic.c provide a frame work for building the library with a mixture of native and emulated functions. This allows the whole library to be provided on all platforms. (I hope.)
I hope this fits with the SDL philosophy of either providing a common subset or emulating when the platform is missing a feature.
I have not added dummy, macosx, or win32 to the build. They are there as place holders for future work.
I have modified congifure.in to compile sources in /src/atomic/linux. (The SDL configure.in file is an amazing piece of work and I hope I didn't mess it up. :-)
author | Bob Pendleton <bob@pendleton.com> |
---|---|
date | Mon, 29 Jun 2009 19:54:43 +0000 |
parents | |
children | 759032c318d8 |
comparison
equal
deleted
inserted
replaced
3201:c297230efc75 | 3202:3aa519a5c676 |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997-2009 Sam Lantinga | |
4 | |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Lesser General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2.1 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Lesser General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Lesser General Public | |
16 License along with this library; if not, write to the Free Software | |
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
18 | |
19 Sam Lantinga | |
20 slouken@libsdl.org | |
21 */ | |
22 | |
23 #include "SDL_stdinc.h" | |
24 #include "SDL_atomic.h" | |
25 | |
26 /* | |
27 This file provides 8, 16, 32, and 64 bit atomic operations. If the | |
28 operations are provided by the native hardware and operating system | |
29 they are used. If they are not then the operations are emulated | |
30 using the SDL mutex operations. | |
31 */ | |
32 | |
33 /* | |
34 First, detect whether the operations are supported and create | |
35 #defines that indicate that they do exist. The goal is to have all | |
36 the system dependent code in the top part of the file so that the | |
37 bottom can be use unchanged across all platforms. | |
38 | |
39 Second, #define all the operations in each size class that are | |
40 supported. Doing this allows supported operations to be used along | |
41 side of emulated operations. | |
42 */ | |
43 | |
44 /* | |
45 Emmulated version. | |
46 | |
47 Assume there is no support for atomic operations. All such | |
48 operations are implemented using SDL mutex operations. | |
49 */ | |
50 | |
51 #ifdef EMULATED_ATOMIC_OPERATIONS | |
52 #undef EMULATED_ATOMIC_OPERATIONS | |
53 #endif | |
54 | |
55 #ifdef EMULATED_ATOMIC_OPERATIONS | |
56 #define HAVE_ALL_8_BIT_OPS | |
57 | |
58 #define nativeExchange8(ptr, value) () | |
59 #define nativeCompareThenSet8(ptr, oldvalue, newvalue) () | |
60 #define nativeTestThenSet8(ptr) () | |
61 #define nativeClear8(ptr) () | |
62 #define nativeFetchThenIncrement8(ptr) () | |
63 #define nativeFetchThenDecrement8(ptr) () | |
64 #define nativeFetchThenAdd8(ptr, value) () | |
65 #define nativeFetchThenSubtract8(ptr, value) () | |
66 #define nativeIncrementThenFetch8(ptr) () | |
67 #define nativeDecrementThenFetch8(ptr) () | |
68 #define nativeAddThenFetch8(ptr, value) () | |
69 #define nativeSubtractThenFetch8(ptr, value) () | |
70 #endif | |
71 | |
72 #ifdef EMULATED_ATOMIC_OPERATIONS | |
73 #define HAVE_ALL_16_BIT_OPS | |
74 | |
75 #define nativeExchange16(ptr, value) () | |
76 #define nativeCompareThenSet16(ptr, oldvalue, newvalue) () | |
77 #define nativeTestThenSet16(ptr) () | |
78 #define nativeClear16(ptr) () | |
79 #define nativeFetchThenIncrement16(ptr) () | |
80 #define nativeFetchThenDecrement16(ptr) () | |
81 #define nativeFetchThenAdd16(ptr, value) () | |
82 #define nativeFetchThenSubtract16(ptr, value) () | |
83 #define nativeIncrementThenFetch16(ptr) () | |
84 #define nativeDecrementThenFetch16(ptr) () | |
85 #define nativeAddThenFetch16(ptr, value) () | |
86 #define nativeSubtractThenFetch16(ptr, value) () | |
87 #endif | |
88 | |
89 #ifdef EMULATED_ATOMIC_OPERATIONS | |
90 #define HAVE_ALL_32_BIT_OPS | |
91 | |
92 #define nativeExchange32(ptr, value) () | |
93 #define nativeCompareThenSet32(ptr, oldvalue, newvalue) () | |
94 #define nativeTestThenSet32(ptr) () | |
95 #define nativeClear32(ptr) () | |
96 #define nativeFetchThenIncrement32(ptr) () | |
97 #define nativeFetchThenDecrement32(ptr) () | |
98 #define nativeFetchThenAdd32(ptr, value) () | |
99 #define nativeFetchThenSubtract32(ptr, value) () | |
100 #define nativeIncrementThenFetch32(ptr) () | |
101 #define nativeDecrementThenFetch32(ptr) () | |
102 #define nativeAddThenFetch32(ptr, value) () | |
103 #define nativeSubtractThenFetch32(ptr, value) () | |
104 #endif | |
105 | |
106 #ifdef EMULATED_ATOMIC_OPERATIONS | |
107 #define HAVE_ALL_64_BIT_OPS | |
108 | |
109 #define nativeExchange64(ptr, value) () | |
110 #define nativeCompareThenSet64(ptr, oldvalue, newvalue) () | |
111 #define nativeTestThenSet64(ptr) () | |
112 #define nativeClear64(ptr) () | |
113 #define nativeFetchThenIncrement64(ptr) () | |
114 #define nativeFetchThenDecrement64(ptr) () | |
115 #define nativeFetchThenAdd64(ptr, value) () | |
116 #define nativeFetchThenSubtract64(ptr, value) () | |
117 #define nativeIncrementThenFetch64(ptr) () | |
118 #define nativeDecrementThenFetch64(ptr) () | |
119 #define nativeAddThenFetch64(ptr, value) () | |
120 #define nativeSubtractThenFetch64(ptr, value) () | |
121 #endif | |
122 | |
123 /* | |
124 If any of the operations are not provided then we must emulate some of | |
125 them. | |
126 */ | |
127 | |
128 #if !defined(HAVE_ALL_8_BIT_OPS) || !defined(HAVE_ALL_16_BIT_OPS) || !defined(HAVE_ALL_32_BIT_OPS) || !defined(HAVE_ALL_64_BIT_OPS) | |
129 | |
130 #include "SDL_mutex.h" | |
131 #include "SDL_error.h" | |
132 | |
133 static SDL_mutex * lock = NULL; | |
134 | |
135 static __inline__ void | |
136 privateWaitLock() | |
137 { | |
138 if(NULL == lock) | |
139 { | |
140 lock = SDL_CreateMutex(); | |
141 if (NULL == lock) | |
142 { | |
143 SDL_SetError("SDL_atomic.c: can't create a mutex"); | |
144 return; | |
145 } | |
146 } | |
147 | |
148 if (-1 == SDL_LockMutex(lock)) | |
149 { | |
150 SDL_SetError("SDL_atomic.c: can't lock mutex"); | |
151 } | |
152 } | |
153 | |
154 static __inline__ void | |
155 privateUnlock() | |
156 { | |
157 if (-1 == SDL_UnlockMutex(lock)) | |
158 { | |
159 SDL_SetError("SDL_atomic.c: can't unlock mutex"); | |
160 } | |
161 } | |
162 | |
163 #endif | |
164 | |
165 /* 8 bit atomic operations */ | |
166 | |
167 Uint8 | |
168 SDL_AtomicExchange8(Uint8 * ptr, Uint8 value) | |
169 { | |
170 #ifdef nativeExchange8 | |
171 return nativeExchange8(ptr, value); | |
172 #else | |
173 Uint8 tmp = 0;; | |
174 | |
175 privateWaitLock(); | |
176 tmp = *ptr; | |
177 *ptr = value; | |
178 privateUnlock(); | |
179 | |
180 return tmp; | |
181 #endif | |
182 } | |
183 | |
184 SDL_bool | |
185 SDL_AtomicCompareThenSet8(Uint8 * ptr, Uint8 oldvalue, Uint8 newvalue) | |
186 { | |
187 #ifdef nativeCompareThenSet8 | |
188 return (SDL_bool)nativeCompareThenSet8(ptr, oldvalue, newvalue); | |
189 #else | |
190 SDL_bool result = SDL_FALSE; | |
191 | |
192 privateWaitLock(); | |
193 result = (*ptr == oldvalue); | |
194 if (result) | |
195 { | |
196 *ptr = newvalue; | |
197 } | |
198 privateUnlock(); | |
199 | |
200 return result; | |
201 #endif | |
202 } | |
203 | |
204 SDL_bool | |
205 SDL_AtomicTestThenSet8(Uint8 * ptr) | |
206 { | |
207 #ifdef nativeTestThenSet8 | |
208 return (SDL_bool)nativeTestThenSet8(ptr); | |
209 #else | |
210 SDL_bool result = SDL_FALSE; | |
211 | |
212 privateWaitLock(); | |
213 result = (*ptr == 0); | |
214 if (result) | |
215 { | |
216 *ptr = 1; | |
217 } | |
218 privateUnlock(); | |
219 | |
220 return result; | |
221 #endif | |
222 } | |
223 | |
224 void | |
225 SDL_AtomicClear8(Uint8 * ptr) | |
226 { | |
227 #ifdef nativeClear8 | |
228 nativeClear8(ptr); | |
229 #else | |
230 privateWaitLock(); | |
231 *ptr = 0; | |
232 privateUnlock(); | |
233 | |
234 return; | |
235 #endif | |
236 } | |
237 | |
238 Uint8 | |
239 SDL_AtomicFetchThenIncrement8(Uint8 * ptr) | |
240 { | |
241 #ifdef nativeFetchThenIncrement8 | |
242 return nativeFetchThenIncrement8(ptr); | |
243 #else | |
244 Uint8 tmp = 0;; | |
245 | |
246 privateWaitLock(); | |
247 tmp = *ptr; | |
248 (*ptr)+= 1; | |
249 privateUnlock(); | |
250 | |
251 return tmp; | |
252 #endif | |
253 } | |
254 | |
255 Uint8 | |
256 SDL_AtomicFetchThenDecrement8(Uint8 * ptr) | |
257 { | |
258 #ifdef nativeFetchThenDecrement8 | |
259 return nativeFetchThenDecrement8(ptr); | |
260 #else | |
261 Uint8 tmp = 0;; | |
262 | |
263 privateWaitLock(); | |
264 tmp = *ptr; | |
265 (*ptr) -= 1; | |
266 privateUnlock(); | |
267 | |
268 return tmp; | |
269 #endif | |
270 } | |
271 | |
272 Uint8 | |
273 SDL_AtomicFetchThenAdd8(Uint8 * ptr, Uint8 value) | |
274 { | |
275 #ifdef nativeFetchThenAdd8 | |
276 return nativeFetchThenAdd8(ptr, value); | |
277 #else | |
278 Uint8 tmp = 0;; | |
279 | |
280 privateWaitLock(); | |
281 tmp = *ptr; | |
282 (*ptr)+= value; | |
283 privateUnlock(); | |
284 | |
285 return tmp; | |
286 #endif | |
287 } | |
288 | |
289 Uint8 | |
290 SDL_AtomicFetchThenSubtract8(Uint8 * ptr, Uint8 value) | |
291 { | |
292 #ifdef nativeFetchThenSubtract8 | |
293 return nativeFetchThenSubtract8(ptr, value); | |
294 #else | |
295 Uint8 tmp = 0;; | |
296 | |
297 privateWaitLock(); | |
298 tmp = *ptr; | |
299 (*ptr)-= value; | |
300 privateUnlock(); | |
301 | |
302 return tmp; | |
303 #endif | |
304 } | |
305 | |
306 Uint8 | |
307 SDL_AtomicIncrementThenFetch8(Uint8 * ptr) | |
308 { | |
309 #ifdef nativeIncrementThenFetch8 | |
310 return nativeIncrementThenFetch8(ptr); | |
311 #else | |
312 Uint8 tmp = 0;; | |
313 | |
314 privateWaitLock(); | |
315 (*ptr)+= 1; | |
316 tmp = *ptr; | |
317 privateUnlock(); | |
318 | |
319 return tmp; | |
320 #endif | |
321 } | |
322 | |
323 Uint8 | |
324 SDL_AtomicDecrementThenFetch8(Uint8 * ptr) | |
325 { | |
326 #ifdef nativeDecrementThenFetch8 | |
327 return nativeDecrementThenFetch8(ptr); | |
328 #else | |
329 Uint8 tmp = 0;; | |
330 | |
331 privateWaitLock(); | |
332 (*ptr)-= 1; | |
333 tmp = *ptr; | |
334 privateUnlock(); | |
335 | |
336 return tmp; | |
337 #endif | |
338 } | |
339 | |
340 Uint8 | |
341 SDL_AtomicAddThenFetch8(Uint8 * ptr, Uint8 value) | |
342 { | |
343 #ifdef nativeAddThenFetch8 | |
344 return nativeAddThenFetch8(ptr, value); | |
345 #else | |
346 Uint8 tmp = 0;; | |
347 | |
348 privateWaitLock(); | |
349 (*ptr)+= value; | |
350 tmp = *ptr; | |
351 privateUnlock(); | |
352 | |
353 return tmp; | |
354 #endif | |
355 } | |
356 | |
357 Uint8 | |
358 SDL_AtomicSubtractThenFetch8(Uint8 * ptr, Uint8 value) | |
359 { | |
360 #ifdef nativeSubtractThenFetch8 | |
361 return nativeSubtractThenFetch8(ptr, value); | |
362 #else | |
363 Uint8 tmp = 0;; | |
364 | |
365 privateWaitLock(); | |
366 (*ptr)-= value; | |
367 tmp = *ptr; | |
368 privateUnlock(); | |
369 | |
370 return tmp; | |
371 #endif | |
372 } | |
373 | |
374 /* 16 bit atomic operations */ | |
375 | |
376 Uint16 | |
377 SDL_AtomicExchange16(Uint16 * ptr, Uint16 value) | |
378 { | |
379 #ifdef nativeExchange16 | |
380 return nativeExchange16(ptr, value); | |
381 #else | |
382 Uint16 tmp = 0;; | |
383 | |
384 privateWaitLock(); | |
385 tmp = *ptr; | |
386 *ptr = value; | |
387 privateUnlock(); | |
388 | |
389 return tmp; | |
390 #endif | |
391 } | |
392 | |
393 SDL_bool | |
394 SDL_AtomicCompareThenSet16(Uint16 * ptr, Uint16 oldvalue, Uint16 newvalue) | |
395 { | |
396 #ifdef nativeCompareThenSet16 | |
397 return (SDL_bool)nativeCompareThenSet16(ptr, oldvalue, newvalue); | |
398 #else | |
399 SDL_bool result = SDL_FALSE; | |
400 | |
401 privateWaitLock(); | |
402 result = (*ptr == oldvalue); | |
403 if (result) | |
404 { | |
405 *ptr = newvalue; | |
406 } | |
407 privateUnlock(); | |
408 | |
409 return result; | |
410 #endif | |
411 } | |
412 | |
413 SDL_bool | |
414 SDL_AtomicTestThenSet16(Uint16 * ptr) | |
415 { | |
416 #ifdef nativeTestThenSet16 | |
417 return (SDL_bool)nativeTestThenSet16(ptr); | |
418 #else | |
419 SDL_bool result = SDL_FALSE; | |
420 | |
421 privateWaitLock(); | |
422 result = (*ptr == 0); | |
423 if (result) | |
424 { | |
425 *ptr = 1; | |
426 } | |
427 privateUnlock(); | |
428 | |
429 return result; | |
430 #endif | |
431 } | |
432 | |
433 void | |
434 SDL_AtomicClear16(Uint16 * ptr) | |
435 { | |
436 #ifdef nativeClear16 | |
437 nativeClear16(ptr); | |
438 #else | |
439 privateWaitLock(); | |
440 *ptr = 0; | |
441 privateUnlock(); | |
442 | |
443 return; | |
444 #endif | |
445 } | |
446 | |
447 Uint16 | |
448 SDL_AtomicFetchThenIncrement16(Uint16 * ptr) | |
449 { | |
450 #ifdef nativeFetchThenIncrement16 | |
451 return nativeFetchThenIncrement16(ptr); | |
452 #else | |
453 Uint16 tmp = 0;; | |
454 | |
455 privateWaitLock(); | |
456 tmp = *ptr; | |
457 (*ptr)+= 1; | |
458 privateUnlock(); | |
459 | |
460 return tmp; | |
461 #endif | |
462 } | |
463 | |
464 Uint16 | |
465 SDL_AtomicFetchThenDecrement16(Uint16 * ptr) | |
466 { | |
467 #ifdef nativeFetchThenDecrement16 | |
468 return nativeFetchThenDecrement16(ptr); | |
469 #else | |
470 Uint16 tmp = 0;; | |
471 | |
472 privateWaitLock(); | |
473 tmp = *ptr; | |
474 (*ptr) -= 1; | |
475 privateUnlock(); | |
476 | |
477 return tmp; | |
478 #endif | |
479 } | |
480 | |
481 Uint16 | |
482 SDL_AtomicFetchThenAdd16(Uint16 * ptr, Uint16 value) | |
483 { | |
484 #ifdef nativeFetchThenAdd16 | |
485 return nativeFetchThenAdd16(ptr, value); | |
486 #else | |
487 Uint16 tmp = 0;; | |
488 | |
489 privateWaitLock(); | |
490 tmp = *ptr; | |
491 (*ptr)+= value; | |
492 privateUnlock(); | |
493 | |
494 return tmp; | |
495 #endif | |
496 } | |
497 | |
498 Uint16 | |
499 SDL_AtomicFetchThenSubtract16(Uint16 * ptr, Uint16 value) | |
500 { | |
501 #ifdef nativeFetchThenSubtract16 | |
502 return nativeFetchThenSubtract16(ptr, value); | |
503 #else | |
504 Uint16 tmp = 0;; | |
505 | |
506 privateWaitLock(); | |
507 tmp = *ptr; | |
508 (*ptr)-= value; | |
509 privateUnlock(); | |
510 | |
511 return tmp; | |
512 #endif | |
513 } | |
514 | |
515 Uint16 | |
516 SDL_AtomicIncrementThenFetch16(Uint16 * ptr) | |
517 { | |
518 #ifdef nativeIncrementThenFetch16 | |
519 return nativeIncrementThenFetch16(ptr); | |
520 #else | |
521 Uint16 tmp = 0;; | |
522 | |
523 privateWaitLock(); | |
524 (*ptr)+= 1; | |
525 tmp = *ptr; | |
526 privateUnlock(); | |
527 | |
528 return tmp; | |
529 #endif | |
530 } | |
531 | |
532 Uint16 | |
533 SDL_AtomicDecrementThenFetch16(Uint16 * ptr) | |
534 { | |
535 #ifdef nativeDecrementThenFetch16 | |
536 return nativeDecrementThenFetch16(ptr); | |
537 #else | |
538 Uint16 tmp = 0;; | |
539 | |
540 privateWaitLock(); | |
541 (*ptr)-= 1; | |
542 tmp = *ptr; | |
543 privateUnlock(); | |
544 | |
545 return tmp; | |
546 #endif | |
547 } | |
548 | |
549 Uint16 | |
550 SDL_AtomicAddThenFetch16(Uint16 * ptr, Uint16 value) | |
551 { | |
552 #ifdef nativeAddThenFetch16 | |
553 return nativeAddThenFetch16(ptr, value); | |
554 #else | |
555 Uint16 tmp = 0;; | |
556 | |
557 privateWaitLock(); | |
558 (*ptr)+= value; | |
559 tmp = *ptr; | |
560 privateUnlock(); | |
561 | |
562 return tmp; | |
563 #endif | |
564 } | |
565 | |
566 Uint16 | |
567 SDL_AtomicSubtractThenFetch16(Uint16 * ptr, Uint16 value) | |
568 { | |
569 #ifdef nativeSubtractThenFetch16 | |
570 return nativeSubtractThenFetch16(ptr, value); | |
571 #else | |
572 Uint16 tmp = 0;; | |
573 | |
574 privateWaitLock(); | |
575 (*ptr)-= value; | |
576 tmp = *ptr; | |
577 privateUnlock(); | |
578 | |
579 return tmp; | |
580 #endif | |
581 } | |
582 | |
583 /* 32 bit atomic operations */ | |
584 | |
585 Uint32 | |
586 SDL_AtomicExchange32(Uint32 * ptr, Uint32 value) | |
587 { | |
588 #ifdef nativeExchange32 | |
589 return nativeExchange32(ptr, value); | |
590 #else | |
591 Uint32 tmp = 0;; | |
592 | |
593 privateWaitLock(); | |
594 tmp = *ptr; | |
595 *ptr = value; | |
596 privateUnlock(); | |
597 | |
598 return tmp; | |
599 #endif | |
600 } | |
601 | |
602 SDL_bool | |
603 SDL_AtomicCompareThenSet32(Uint32 * ptr, Uint32 oldvalue, Uint32 newvalue) | |
604 { | |
605 #ifdef nativeCompareThenSet32 | |
606 return (SDL_bool)nativeCompareThenSet32(ptr, oldvalue, newvalue); | |
607 #else | |
608 SDL_bool result = SDL_FALSE; | |
609 | |
610 privateWaitLock(); | |
611 result = (*ptr == oldvalue); | |
612 if (result) | |
613 { | |
614 *ptr = newvalue; | |
615 } | |
616 privateUnlock(); | |
617 | |
618 return result; | |
619 #endif | |
620 } | |
621 | |
622 SDL_bool | |
623 SDL_AtomicTestThenSet32(Uint32 * ptr) | |
624 { | |
625 #ifdef nativeTestThenSet32 | |
626 return (SDL_bool)nativeTestThenSet32(ptr); | |
627 #else | |
628 SDL_bool result = SDL_FALSE; | |
629 | |
630 privateWaitLock(); | |
631 result = (*ptr == 0); | |
632 if (result) | |
633 { | |
634 *ptr = 1; | |
635 } | |
636 privateUnlock(); | |
637 | |
638 return result; | |
639 #endif | |
640 } | |
641 | |
642 void | |
643 SDL_AtomicClear32(Uint32 * ptr) | |
644 { | |
645 #ifdef nativeClear32 | |
646 nativeClear32(ptr); | |
647 #else | |
648 privateWaitLock(); | |
649 *ptr = 0; | |
650 privateUnlock(); | |
651 | |
652 return; | |
653 #endif | |
654 } | |
655 | |
656 Uint32 | |
657 SDL_AtomicFetchThenIncrement32(Uint32 * ptr) | |
658 { | |
659 #ifdef nativeFetchThenIncrement32 | |
660 return nativeFetchThenIncrement32(ptr); | |
661 #else | |
662 Uint32 tmp = 0;; | |
663 | |
664 privateWaitLock(); | |
665 tmp = *ptr; | |
666 (*ptr)+= 1; | |
667 privateUnlock(); | |
668 | |
669 return tmp; | |
670 #endif | |
671 } | |
672 | |
673 Uint32 | |
674 SDL_AtomicFetchThenDecrement32(Uint32 * ptr) | |
675 { | |
676 #ifdef nativeFetchThenDecrement32 | |
677 return nativeFetchThenDecrement32(ptr); | |
678 #else | |
679 Uint32 tmp = 0;; | |
680 | |
681 privateWaitLock(); | |
682 tmp = *ptr; | |
683 (*ptr) -= 1; | |
684 privateUnlock(); | |
685 | |
686 return tmp; | |
687 #endif | |
688 } | |
689 | |
690 Uint32 | |
691 SDL_AtomicFetchThenAdd32(Uint32 * ptr, Uint32 value) | |
692 { | |
693 #ifdef nativeFetchThenAdd32 | |
694 return nativeFetchThenAdd32(ptr, value); | |
695 #else | |
696 Uint32 tmp = 0;; | |
697 | |
698 privateWaitLock(); | |
699 tmp = *ptr; | |
700 (*ptr)+= value; | |
701 privateUnlock(); | |
702 | |
703 return tmp; | |
704 #endif | |
705 } | |
706 | |
707 Uint32 | |
708 SDL_AtomicFetchThenSubtract32(Uint32 * ptr, Uint32 value) | |
709 { | |
710 #ifdef nativeFetchThenSubtract32 | |
711 return nativeFetchThenSubtract32(ptr, value); | |
712 #else | |
713 Uint32 tmp = 0;; | |
714 | |
715 privateWaitLock(); | |
716 tmp = *ptr; | |
717 (*ptr)-= value; | |
718 privateUnlock(); | |
719 | |
720 return tmp; | |
721 #endif | |
722 } | |
723 | |
724 Uint32 | |
725 SDL_AtomicIncrementThenFetch32(Uint32 * ptr) | |
726 { | |
727 #ifdef nativeIncrementThenFetch32 | |
728 return nativeIncrementThenFetch32(ptr); | |
729 #else | |
730 Uint32 tmp = 0;; | |
731 | |
732 privateWaitLock(); | |
733 (*ptr)+= 1; | |
734 tmp = *ptr; | |
735 privateUnlock(); | |
736 | |
737 return tmp; | |
738 #endif | |
739 } | |
740 | |
741 Uint32 | |
742 SDL_AtomicDecrementThenFetch32(Uint32 * ptr) | |
743 { | |
744 #ifdef nativeDecrementThenFetch32 | |
745 return nativeDecrementThenFetch32(ptr); | |
746 #else | |
747 Uint32 tmp = 0;; | |
748 | |
749 privateWaitLock(); | |
750 (*ptr)-= 1; | |
751 tmp = *ptr; | |
752 privateUnlock(); | |
753 | |
754 return tmp; | |
755 #endif | |
756 } | |
757 | |
758 Uint32 | |
759 SDL_AtomicAddThenFetch32(Uint32 * ptr, Uint32 value) | |
760 { | |
761 #ifdef nativeAddThenFetch32 | |
762 return nativeAddThenFetch32(ptr, value); | |
763 #else | |
764 Uint32 tmp = 0;; | |
765 | |
766 privateWaitLock(); | |
767 (*ptr)+= value; | |
768 tmp = *ptr; | |
769 privateUnlock(); | |
770 | |
771 return tmp; | |
772 #endif | |
773 } | |
774 | |
775 Uint32 | |
776 SDL_AtomicSubtractThenFetch32(Uint32 * ptr, Uint32 value) | |
777 { | |
778 #ifdef nativeSubtractThenFetch32 | |
779 return nativeSubtractThenFetch32(ptr, value); | |
780 #else | |
781 Uint32 tmp = 0;; | |
782 | |
783 privateWaitLock(); | |
784 (*ptr)-= value; | |
785 tmp = *ptr; | |
786 privateUnlock(); | |
787 | |
788 return tmp; | |
789 #endif | |
790 } | |
791 | |
792 /* 64 bit atomic operations */ | |
793 #ifdef SDL_HAS_64BIT_TYPE | |
794 | |
795 Uint64 | |
796 SDL_AtomicExchange64(Uint64 * ptr, Uint64 value) | |
797 { | |
798 #ifdef nativeExchange64 | |
799 return nativeExchange64(ptr, value); | |
800 #else | |
801 Uint64 tmp = 0;; | |
802 | |
803 privateWaitLock(); | |
804 tmp = *ptr; | |
805 *ptr = value; | |
806 privateUnlock(); | |
807 | |
808 return tmp; | |
809 #endif | |
810 } | |
811 | |
812 SDL_bool | |
813 SDL_AtomicCompareThenSet64(Uint64 * ptr, Uint64 oldvalue, Uint64 newvalue) | |
814 { | |
815 #ifdef nativeCompareThenSet64 | |
816 return (SDL_bool)nativeCompareThenSet64(ptr, oldvalue, newvalue); | |
817 #else | |
818 SDL_bool result = SDL_FALSE; | |
819 | |
820 privateWaitLock(); | |
821 result = (*ptr == oldvalue); | |
822 if (result) | |
823 { | |
824 *ptr = newvalue; | |
825 } | |
826 privateUnlock(); | |
827 | |
828 return result; | |
829 #endif | |
830 } | |
831 | |
832 SDL_bool | |
833 SDL_AtomicTestThenSet64(Uint64 * ptr) | |
834 { | |
835 #ifdef nativeTestThenSet64 | |
836 return (SDL_bool)nativeTestThenSet64(ptr); | |
837 #else | |
838 SDL_bool result = SDL_FALSE; | |
839 | |
840 privateWaitLock(); | |
841 result = (*ptr == 0); | |
842 if (result) | |
843 { | |
844 *ptr = 1; | |
845 } | |
846 privateUnlock(); | |
847 | |
848 return result; | |
849 #endif | |
850 } | |
851 | |
852 void | |
853 SDL_AtomicClear64(Uint64 * ptr) | |
854 { | |
855 #ifdef nativeClear64 | |
856 nativeClear64(ptr); | |
857 #else | |
858 privateWaitLock(); | |
859 *ptr = 0; | |
860 privateUnlock(); | |
861 | |
862 return; | |
863 #endif | |
864 } | |
865 | |
866 Uint64 | |
867 SDL_AtomicFetchThenIncrement64(Uint64 * ptr) | |
868 { | |
869 #ifdef nativeFetchThenIncrement64 | |
870 return nativeFetchThenIncrement64(ptr); | |
871 #else | |
872 Uint64 tmp = 0;; | |
873 | |
874 privateWaitLock(); | |
875 tmp = *ptr; | |
876 (*ptr)+= 1; | |
877 privateUnlock(); | |
878 | |
879 return tmp; | |
880 #endif | |
881 } | |
882 | |
883 Uint64 | |
884 SDL_AtomicFetchThenDecrement64(Uint64 * ptr) | |
885 { | |
886 #ifdef nativeFetchThenDecrement64 | |
887 return nativeFetchThenDecrement64(ptr); | |
888 #else | |
889 Uint64 tmp = 0;; | |
890 | |
891 privateWaitLock(); | |
892 tmp = *ptr; | |
893 (*ptr) -= 1; | |
894 privateUnlock(); | |
895 | |
896 return tmp; | |
897 #endif | |
898 } | |
899 | |
900 Uint64 | |
901 SDL_AtomicFetchThenAdd64(Uint64 * ptr, Uint64 value) | |
902 { | |
903 #ifdef nativeFetchThenAdd64 | |
904 return nativeFetchThenAdd64(ptr, value); | |
905 #else | |
906 Uint64 tmp = 0;; | |
907 | |
908 privateWaitLock(); | |
909 tmp = *ptr; | |
910 (*ptr)+= value; | |
911 privateUnlock(); | |
912 | |
913 return tmp; | |
914 #endif | |
915 } | |
916 | |
917 Uint64 | |
918 SDL_AtomicFetchThenSubtract64(Uint64 * ptr, Uint64 value) | |
919 { | |
920 #ifdef nativeFetchThenSubtract64 | |
921 return nativeFetchThenSubtract64(ptr, value); | |
922 #else | |
923 Uint64 tmp = 0;; | |
924 | |
925 privateWaitLock(); | |
926 tmp = *ptr; | |
927 (*ptr)-= value; | |
928 privateUnlock(); | |
929 | |
930 return tmp; | |
931 #endif | |
932 } | |
933 | |
934 Uint64 | |
935 SDL_AtomicIncrementThenFetch64(Uint64 * ptr) | |
936 { | |
937 #ifdef nativeIncrementThenFetch64 | |
938 return nativeIncrementThenFetch64(ptr); | |
939 #else | |
940 Uint64 tmp = 0;; | |
941 | |
942 privateWaitLock(); | |
943 (*ptr)+= 1; | |
944 tmp = *ptr; | |
945 privateUnlock(); | |
946 | |
947 return tmp; | |
948 #endif | |
949 } | |
950 | |
951 Uint64 | |
952 SDL_AtomicDecrementThenFetch64(Uint64 * ptr) | |
953 { | |
954 #ifdef nativeDecrementThenFetch64 | |
955 return nativeDecrementThenFetch64(ptr); | |
956 #else | |
957 Uint64 tmp = 0;; | |
958 | |
959 privateWaitLock(); | |
960 (*ptr)-= 1; | |
961 tmp = *ptr; | |
962 privateUnlock(); | |
963 | |
964 return tmp; | |
965 #endif | |
966 } | |
967 | |
968 Uint64 | |
969 SDL_AtomicAddThenFetch64(Uint64 * ptr, Uint64 value) | |
970 { | |
971 #ifdef nativeAddThenFetch64 | |
972 return nativeAddThenFetch64(ptr, value); | |
973 #else | |
974 Uint64 tmp = 0;; | |
975 | |
976 privateWaitLock(); | |
977 (*ptr)+= value; | |
978 tmp = *ptr; | |
979 privateUnlock(); | |
980 | |
981 return tmp; | |
982 #endif | |
983 } | |
984 | |
985 Uint64 | |
986 SDL_AtomicSubtractThenFetch64(Uint64 * ptr, Uint64 value) | |
987 { | |
988 #ifdef nativeSubtractThenFetch64 | |
989 return nativeSubtractThenFetch64(ptr, value); | |
990 #else | |
991 Uint64 tmp = 0;; | |
992 | |
993 privateWaitLock(); | |
994 (*ptr)-= value; | |
995 tmp = *ptr; | |
996 privateUnlock(); | |
997 | |
998 return tmp; | |
999 #endif | |
1000 } | |
1001 #endif | |
1002 |