Mercurial > sdl-ios-xcode
comparison src/atomic/qnx/SDL_atomic.c @ 3217:26ce0b98f2fb
Support for native and emulated atomic operations has been added.
author | Mike Gorchak <lestat@i.com.ua> |
---|---|
date | Sun, 19 Jul 2009 08:04:59 +0000 |
parents | |
children | 70bfe3337f8a |
comparison
equal
deleted
inserted
replaced
3216:48a80f2a7ff2 | 3217:26ce0b98f2fb |
---|---|
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 #include <atomic.h> | |
27 | |
28 /* | |
29 This file provides 8, 16, 32, and 64 bit atomic operations. If the | |
30 operations are provided by the native hardware and operating system | |
31 they are used. If they are not then the operations are emulated | |
32 using the SDL mutex operations. | |
33 */ | |
34 | |
35 /* | |
36 First, detect whether the operations are supported and create | |
37 #defines that indicate that they do exist. The goal is to have all | |
38 the system dependent code in the top part of the file so that the | |
39 bottom can be use unchanged across all platforms. | |
40 | |
41 Second, #define all the operations in each size class that are | |
42 supported. Doing this allows supported operations to be used along | |
43 side of emulated operations. | |
44 */ | |
45 | |
46 /* | |
47 Emmulated version. | |
48 | |
49 Assume there is no support for atomic operations. All such | |
50 operations are implemented using SDL mutex operations. | |
51 */ | |
52 | |
53 #ifdef EMULATED_ATOMIC_OPERATIONS | |
54 #undef EMULATED_ATOMIC_OPERATIONS | |
55 #endif | |
56 | |
57 #ifdef EMULATED_ATOMIC_OPERATIONS | |
58 #define HAVE_ALL_8_BIT_OPS | |
59 | |
60 #define nativeExchange8(ptr, value) () | |
61 #define nativeCompareThenSet8(ptr, oldvalue, newvalue) () | |
62 #define nativeTestThenSet8(ptr) () | |
63 #define nativeClear8(ptr) () | |
64 #define nativeFetchThenIncrement8(ptr) () | |
65 #define nativeFetchThenDecrement8(ptr) () | |
66 #define nativeFetchThenAdd8(ptr, value) () | |
67 #define nativeFetchThenSubtract8(ptr, value) () | |
68 #define nativeIncrementThenFetch8(ptr) () | |
69 #define nativeDecrementThenFetch8(ptr) () | |
70 #define nativeAddThenFetch8(ptr, value) () | |
71 #define nativeSubtractThenFetch8(ptr, value) () | |
72 #endif | |
73 | |
74 #ifdef EMULATED_ATOMIC_OPERATIONS | |
75 #define HAVE_ALL_16_BIT_OPS | |
76 | |
77 #define nativeExchange16(ptr, value) () | |
78 #define nativeCompareThenSet16(ptr, oldvalue, newvalue) () | |
79 #define nativeTestThenSet16(ptr) () | |
80 #define nativeClear16(ptr) () | |
81 #define nativeFetchThenIncrement16(ptr) () | |
82 #define nativeFetchThenDecrement16(ptr) () | |
83 #define nativeFetchThenAdd16(ptr, value) () | |
84 #define nativeFetchThenSubtract16(ptr, value) () | |
85 #define nativeIncrementThenFetch16(ptr) () | |
86 #define nativeDecrementThenFetch16(ptr) () | |
87 #define nativeAddThenFetch16(ptr, value) () | |
88 #define nativeSubtractThenFetch16(ptr, value) () | |
89 #endif | |
90 | |
91 #ifdef EMULATED_ATOMIC_OPERATIONS | |
92 #define HAVE_ALL_64_BIT_OPS | |
93 | |
94 #define nativeExchange64(ptr, value) () | |
95 #define nativeCompareThenSet64(ptr, oldvalue, newvalue) () | |
96 #define nativeTestThenSet64(ptr) () | |
97 #define nativeClear64(ptr) () | |
98 #define nativeFetchThenIncrement64(ptr) () | |
99 #define nativeFetchThenDecrement64(ptr) () | |
100 #define nativeFetchThenAdd64(ptr, value) () | |
101 #define nativeFetchThenSubtract64(ptr, value) () | |
102 #define nativeIncrementThenFetch64(ptr) () | |
103 #define nativeDecrementThenFetch64(ptr) () | |
104 #define nativeAddThenFetch64(ptr, value) () | |
105 #define nativeSubtractThenFetch64(ptr, value) () | |
106 #endif | |
107 | |
108 /* | |
109 If any of the operations are not provided then we must emulate some of | |
110 them. | |
111 */ | |
112 | |
113 #if !defined(HAVE_ALL_8_BIT_OPS) || !defined(HAVE_ALL_16_BIT_OPS) || !defined(HAVE_ALL_64_BIT_OPS) | |
114 | |
115 #include "SDL_mutex.h" | |
116 #include "SDL_error.h" | |
117 | |
118 static SDL_mutex * lock = NULL; | |
119 | |
120 static __inline__ void | |
121 privateWaitLock() | |
122 { | |
123 if(NULL == lock) | |
124 { | |
125 lock = SDL_CreateMutex(); | |
126 if (NULL == lock) | |
127 { | |
128 SDL_SetError("SDL_atomic.c: can't create a mutex"); | |
129 return; | |
130 } | |
131 } | |
132 | |
133 if (-1 == SDL_LockMutex(lock)) | |
134 { | |
135 SDL_SetError("SDL_atomic.c: can't lock mutex"); | |
136 } | |
137 } | |
138 | |
139 static __inline__ void | |
140 privateUnlock() | |
141 { | |
142 if (-1 == SDL_UnlockMutex(lock)) | |
143 { | |
144 SDL_SetError("SDL_atomic.c: can't unlock mutex"); | |
145 } | |
146 } | |
147 | |
148 #endif | |
149 | |
150 /* 8 bit atomic operations */ | |
151 | |
152 Uint8 | |
153 SDL_AtomicExchange8(volatile Uint8 * ptr, Uint8 value) | |
154 { | |
155 #ifdef nativeExchange8 | |
156 return nativeExchange8(ptr, value); | |
157 #else | |
158 Uint8 tmp = 0; | |
159 | |
160 privateWaitLock(); | |
161 tmp = *ptr; | |
162 *ptr = value; | |
163 privateUnlock(); | |
164 | |
165 return tmp; | |
166 #endif | |
167 } | |
168 | |
169 SDL_bool | |
170 SDL_AtomicCompareThenSet8(volatile Uint8 * ptr, Uint8 oldvalue, Uint8 newvalue) | |
171 { | |
172 #ifdef nativeCompareThenSet8 | |
173 return (SDL_bool)nativeCompareThenSet8(ptr, oldvalue, newvalue); | |
174 #else | |
175 SDL_bool result = SDL_FALSE; | |
176 | |
177 privateWaitLock(); | |
178 result = (*ptr == oldvalue); | |
179 if (result) | |
180 { | |
181 *ptr = newvalue; | |
182 } | |
183 privateUnlock(); | |
184 | |
185 return result; | |
186 #endif | |
187 } | |
188 | |
189 SDL_bool | |
190 SDL_AtomicTestThenSet8(volatile Uint8 * ptr) | |
191 { | |
192 #ifdef nativeTestThenSet8 | |
193 return (SDL_bool)nativeTestThenSet8(ptr); | |
194 #else | |
195 SDL_bool result = SDL_FALSE; | |
196 | |
197 privateWaitLock(); | |
198 result = (*ptr == 0); | |
199 if (result) | |
200 { | |
201 *ptr = 1; | |
202 } | |
203 privateUnlock(); | |
204 | |
205 return result; | |
206 #endif | |
207 } | |
208 | |
209 void | |
210 SDL_AtomicClear8(volatile Uint8 * ptr) | |
211 { | |
212 #ifdef nativeClear8 | |
213 nativeClear8(ptr); | |
214 #else | |
215 privateWaitLock(); | |
216 *ptr = 0; | |
217 privateUnlock(); | |
218 | |
219 return; | |
220 #endif | |
221 } | |
222 | |
223 Uint8 | |
224 SDL_AtomicFetchThenIncrement8(volatile Uint8 * ptr) | |
225 { | |
226 #ifdef nativeFetchThenIncrement8 | |
227 return nativeFetchThenIncrement8(ptr); | |
228 #else | |
229 Uint8 tmp = 0; | |
230 | |
231 privateWaitLock(); | |
232 tmp = *ptr; | |
233 (*ptr)+= 1; | |
234 privateUnlock(); | |
235 | |
236 return tmp; | |
237 #endif | |
238 } | |
239 | |
240 Uint8 | |
241 SDL_AtomicFetchThenDecrement8(volatile Uint8 * ptr) | |
242 { | |
243 #ifdef nativeFetchThenDecrement8 | |
244 return nativeFetchThenDecrement8(ptr); | |
245 #else | |
246 Uint8 tmp = 0; | |
247 | |
248 privateWaitLock(); | |
249 tmp = *ptr; | |
250 (*ptr) -= 1; | |
251 privateUnlock(); | |
252 | |
253 return tmp; | |
254 #endif | |
255 } | |
256 | |
257 Uint8 | |
258 SDL_AtomicFetchThenAdd8(volatile Uint8 * ptr, Uint8 value) | |
259 { | |
260 #ifdef nativeFetchThenAdd8 | |
261 return nativeFetchThenAdd8(ptr, value); | |
262 #else | |
263 Uint8 tmp = 0; | |
264 | |
265 privateWaitLock(); | |
266 tmp = *ptr; | |
267 (*ptr)+= value; | |
268 privateUnlock(); | |
269 | |
270 return tmp; | |
271 #endif | |
272 } | |
273 | |
274 Uint8 | |
275 SDL_AtomicFetchThenSubtract8(volatile Uint8 * ptr, Uint8 value) | |
276 { | |
277 #ifdef nativeFetchThenSubtract8 | |
278 return nativeFetchThenSubtract8(ptr, value); | |
279 #else | |
280 Uint8 tmp = 0; | |
281 | |
282 privateWaitLock(); | |
283 tmp = *ptr; | |
284 (*ptr)-= value; | |
285 privateUnlock(); | |
286 | |
287 return tmp; | |
288 #endif | |
289 } | |
290 | |
291 Uint8 | |
292 SDL_AtomicIncrementThenFetch8(volatile Uint8 * ptr) | |
293 { | |
294 #ifdef nativeIncrementThenFetch8 | |
295 return nativeIncrementThenFetch8(ptr); | |
296 #else | |
297 Uint8 tmp = 0; | |
298 | |
299 privateWaitLock(); | |
300 (*ptr)+= 1; | |
301 tmp = *ptr; | |
302 privateUnlock(); | |
303 | |
304 return tmp; | |
305 #endif | |
306 } | |
307 | |
308 Uint8 | |
309 SDL_AtomicDecrementThenFetch8(volatile Uint8 * ptr) | |
310 { | |
311 #ifdef nativeDecrementThenFetch8 | |
312 return nativeDecrementThenFetch8(ptr); | |
313 #else | |
314 Uint8 tmp = 0; | |
315 | |
316 privateWaitLock(); | |
317 (*ptr)-= 1; | |
318 tmp = *ptr; | |
319 privateUnlock(); | |
320 | |
321 return tmp; | |
322 #endif | |
323 } | |
324 | |
325 Uint8 | |
326 SDL_AtomicAddThenFetch8(volatile Uint8 * ptr, Uint8 value) | |
327 { | |
328 #ifdef nativeAddThenFetch8 | |
329 return nativeAddThenFetch8(ptr, value); | |
330 #else | |
331 Uint8 tmp = 0; | |
332 | |
333 privateWaitLock(); | |
334 (*ptr)+= value; | |
335 tmp = *ptr; | |
336 privateUnlock(); | |
337 | |
338 return tmp; | |
339 #endif | |
340 } | |
341 | |
342 Uint8 | |
343 SDL_AtomicSubtractThenFetch8(volatile Uint8 * ptr, Uint8 value) | |
344 { | |
345 #ifdef nativeSubtractThenFetch8 | |
346 return nativeSubtractThenFetch8(ptr, value); | |
347 #else | |
348 Uint8 tmp = 0; | |
349 | |
350 privateWaitLock(); | |
351 (*ptr)-= value; | |
352 tmp = *ptr; | |
353 privateUnlock(); | |
354 | |
355 return tmp; | |
356 #endif | |
357 } | |
358 | |
359 /* 16 bit atomic operations */ | |
360 | |
361 Uint16 | |
362 SDL_AtomicExchange16(volatile Uint16 * ptr, Uint16 value) | |
363 { | |
364 #ifdef nativeExchange16 | |
365 return nativeExchange16(ptr, value); | |
366 #else | |
367 Uint16 tmp = 0; | |
368 | |
369 privateWaitLock(); | |
370 tmp = *ptr; | |
371 *ptr = value; | |
372 privateUnlock(); | |
373 | |
374 return tmp; | |
375 #endif | |
376 } | |
377 | |
378 SDL_bool | |
379 SDL_AtomicCompareThenSet16(volatile Uint16 * ptr, Uint16 oldvalue, Uint16 newvalue) | |
380 { | |
381 #ifdef nativeCompareThenSet16 | |
382 return (SDL_bool)nativeCompareThenSet16(ptr, oldvalue, newvalue); | |
383 #else | |
384 SDL_bool result = SDL_FALSE; | |
385 | |
386 privateWaitLock(); | |
387 result = (*ptr == oldvalue); | |
388 if (result) | |
389 { | |
390 *ptr = newvalue; | |
391 } | |
392 privateUnlock(); | |
393 | |
394 return result; | |
395 #endif | |
396 } | |
397 | |
398 SDL_bool | |
399 SDL_AtomicTestThenSet16(volatile Uint16 * ptr) | |
400 { | |
401 #ifdef nativeTestThenSet16 | |
402 return (SDL_bool)nativeTestThenSet16(ptr); | |
403 #else | |
404 SDL_bool result = SDL_FALSE; | |
405 | |
406 privateWaitLock(); | |
407 result = (*ptr == 0); | |
408 if (result) | |
409 { | |
410 *ptr = 1; | |
411 } | |
412 privateUnlock(); | |
413 | |
414 return result; | |
415 #endif | |
416 } | |
417 | |
418 void | |
419 SDL_AtomicClear16(volatile Uint16 * ptr) | |
420 { | |
421 #ifdef nativeClear16 | |
422 nativeClear16(ptr); | |
423 #else | |
424 privateWaitLock(); | |
425 *ptr = 0; | |
426 privateUnlock(); | |
427 | |
428 return; | |
429 #endif | |
430 } | |
431 | |
432 Uint16 | |
433 SDL_AtomicFetchThenIncrement16(volatile Uint16 * ptr) | |
434 { | |
435 #ifdef nativeFetchThenIncrement16 | |
436 return nativeFetchThenIncrement16(ptr); | |
437 #else | |
438 Uint16 tmp = 0; | |
439 | |
440 privateWaitLock(); | |
441 tmp = *ptr; | |
442 (*ptr)+= 1; | |
443 privateUnlock(); | |
444 | |
445 return tmp; | |
446 #endif | |
447 } | |
448 | |
449 Uint16 | |
450 SDL_AtomicFetchThenDecrement16(volatile Uint16 * ptr) | |
451 { | |
452 #ifdef nativeFetchThenDecrement16 | |
453 return nativeFetchThenDecrement16(ptr); | |
454 #else | |
455 Uint16 tmp = 0; | |
456 | |
457 privateWaitLock(); | |
458 tmp = *ptr; | |
459 (*ptr) -= 1; | |
460 privateUnlock(); | |
461 | |
462 return tmp; | |
463 #endif | |
464 } | |
465 | |
466 Uint16 | |
467 SDL_AtomicFetchThenAdd16(volatile Uint16 * ptr, Uint16 value) | |
468 { | |
469 #ifdef nativeFetchThenAdd16 | |
470 return nativeFetchThenAdd16(ptr, value); | |
471 #else | |
472 Uint16 tmp = 0; | |
473 | |
474 privateWaitLock(); | |
475 tmp = *ptr; | |
476 (*ptr)+= value; | |
477 privateUnlock(); | |
478 | |
479 return tmp; | |
480 #endif | |
481 } | |
482 | |
483 Uint16 | |
484 SDL_AtomicFetchThenSubtract16(volatile Uint16 * ptr, Uint16 value) | |
485 { | |
486 #ifdef nativeFetchThenSubtract16 | |
487 return nativeFetchThenSubtract16(ptr, value); | |
488 #else | |
489 Uint16 tmp = 0; | |
490 | |
491 privateWaitLock(); | |
492 tmp = *ptr; | |
493 (*ptr)-= value; | |
494 privateUnlock(); | |
495 | |
496 return tmp; | |
497 #endif | |
498 } | |
499 | |
500 Uint16 | |
501 SDL_AtomicIncrementThenFetch16(volatile Uint16 * ptr) | |
502 { | |
503 #ifdef nativeIncrementThenFetch16 | |
504 return nativeIncrementThenFetch16(ptr); | |
505 #else | |
506 Uint16 tmp = 0; | |
507 | |
508 privateWaitLock(); | |
509 (*ptr)+= 1; | |
510 tmp = *ptr; | |
511 privateUnlock(); | |
512 | |
513 return tmp; | |
514 #endif | |
515 } | |
516 | |
517 Uint16 | |
518 SDL_AtomicDecrementThenFetch16(volatile Uint16 * ptr) | |
519 { | |
520 #ifdef nativeDecrementThenFetch16 | |
521 return nativeDecrementThenFetch16(ptr); | |
522 #else | |
523 Uint16 tmp = 0; | |
524 | |
525 privateWaitLock(); | |
526 (*ptr)-= 1; | |
527 tmp = *ptr; | |
528 privateUnlock(); | |
529 | |
530 return tmp; | |
531 #endif | |
532 } | |
533 | |
534 Uint16 | |
535 SDL_AtomicAddThenFetch16(volatile Uint16 * ptr, Uint16 value) | |
536 { | |
537 #ifdef nativeAddThenFetch16 | |
538 return nativeAddThenFetch16(ptr, value); | |
539 #else | |
540 Uint16 tmp = 0; | |
541 | |
542 privateWaitLock(); | |
543 (*ptr)+= value; | |
544 tmp = *ptr; | |
545 privateUnlock(); | |
546 | |
547 return tmp; | |
548 #endif | |
549 } | |
550 | |
551 Uint16 | |
552 SDL_AtomicSubtractThenFetch16(volatile Uint16 * ptr, Uint16 value) | |
553 { | |
554 #ifdef nativeSubtractThenFetch16 | |
555 return nativeSubtractThenFetch16(ptr, value); | |
556 #else | |
557 Uint16 tmp = 0; | |
558 | |
559 privateWaitLock(); | |
560 (*ptr)-= value; | |
561 tmp = *ptr; | |
562 privateUnlock(); | |
563 | |
564 return tmp; | |
565 #endif | |
566 } | |
567 | |
568 /* 64 bit atomic operations */ | |
569 #ifdef SDL_HAS_64BIT_TYPE | |
570 | |
571 Uint64 | |
572 SDL_AtomicExchange64(volatile Uint64 * ptr, Uint64 value) | |
573 { | |
574 #ifdef nativeExchange64 | |
575 return nativeExchange64(ptr, value); | |
576 #else | |
577 Uint64 tmp = 0; | |
578 | |
579 privateWaitLock(); | |
580 tmp = *ptr; | |
581 *ptr = value; | |
582 privateUnlock(); | |
583 | |
584 return tmp; | |
585 #endif | |
586 } | |
587 | |
588 SDL_bool | |
589 SDL_AtomicCompareThenSet64(volatile Uint64 * ptr, Uint64 oldvalue, Uint64 newvalue) | |
590 { | |
591 #ifdef nativeCompareThenSet64 | |
592 return (SDL_bool)nativeCompareThenSet64(ptr, oldvalue, newvalue); | |
593 #else | |
594 SDL_bool result = SDL_FALSE; | |
595 | |
596 privateWaitLock(); | |
597 result = (*ptr == oldvalue); | |
598 if (result) | |
599 { | |
600 *ptr = newvalue; | |
601 } | |
602 privateUnlock(); | |
603 | |
604 return result; | |
605 #endif | |
606 } | |
607 | |
608 SDL_bool | |
609 SDL_AtomicTestThenSet64(volatile Uint64 * ptr) | |
610 { | |
611 #ifdef nativeTestThenSet64 | |
612 return (SDL_bool)nativeTestThenSet64(ptr); | |
613 #else | |
614 SDL_bool result = SDL_FALSE; | |
615 | |
616 privateWaitLock(); | |
617 result = (*ptr == 0); | |
618 if (result) | |
619 { | |
620 *ptr = 1; | |
621 } | |
622 privateUnlock(); | |
623 | |
624 return result; | |
625 #endif | |
626 } | |
627 | |
628 void | |
629 SDL_AtomicClear64(volatile Uint64 * ptr) | |
630 { | |
631 #ifdef nativeClear64 | |
632 nativeClear64(ptr); | |
633 #else | |
634 privateWaitLock(); | |
635 *ptr = 0; | |
636 privateUnlock(); | |
637 | |
638 return; | |
639 #endif | |
640 } | |
641 | |
642 Uint64 | |
643 SDL_AtomicFetchThenIncrement64(volatile Uint64 * ptr) | |
644 { | |
645 #ifdef nativeFetchThenIncrement64 | |
646 return nativeFetchThenIncrement64(ptr); | |
647 #else | |
648 Uint64 tmp = 0; | |
649 | |
650 privateWaitLock(); | |
651 tmp = *ptr; | |
652 (*ptr)+= 1; | |
653 privateUnlock(); | |
654 | |
655 return tmp; | |
656 #endif | |
657 } | |
658 | |
659 Uint64 | |
660 SDL_AtomicFetchThenDecrement64(volatile Uint64 * ptr) | |
661 { | |
662 #ifdef nativeFetchThenDecrement64 | |
663 return nativeFetchThenDecrement64(ptr); | |
664 #else | |
665 Uint64 tmp = 0; | |
666 | |
667 privateWaitLock(); | |
668 tmp = *ptr; | |
669 (*ptr) -= 1; | |
670 privateUnlock(); | |
671 | |
672 return tmp; | |
673 #endif | |
674 } | |
675 | |
676 Uint64 | |
677 SDL_AtomicFetchThenAdd64(volatile Uint64 * ptr, Uint64 value) | |
678 { | |
679 #ifdef nativeFetchThenAdd64 | |
680 return nativeFetchThenAdd64(ptr, value); | |
681 #else | |
682 Uint64 tmp = 0; | |
683 | |
684 privateWaitLock(); | |
685 tmp = *ptr; | |
686 (*ptr)+= value; | |
687 privateUnlock(); | |
688 | |
689 return tmp; | |
690 #endif | |
691 } | |
692 | |
693 Uint64 | |
694 SDL_AtomicFetchThenSubtract64(volatile Uint64 * ptr, Uint64 value) | |
695 { | |
696 #ifdef nativeFetchThenSubtract64 | |
697 return nativeFetchThenSubtract64(ptr, value); | |
698 #else | |
699 Uint64 tmp = 0; | |
700 | |
701 privateWaitLock(); | |
702 tmp = *ptr; | |
703 (*ptr)-= value; | |
704 privateUnlock(); | |
705 | |
706 return tmp; | |
707 #endif | |
708 } | |
709 | |
710 Uint64 | |
711 SDL_AtomicIncrementThenFetch64(volatile Uint64 * ptr) | |
712 { | |
713 #ifdef nativeIncrementThenFetch64 | |
714 return nativeIncrementThenFetch64(ptr); | |
715 #else | |
716 Uint64 tmp = 0; | |
717 | |
718 privateWaitLock(); | |
719 (*ptr)+= 1; | |
720 tmp = *ptr; | |
721 privateUnlock(); | |
722 | |
723 return tmp; | |
724 #endif | |
725 } | |
726 | |
727 Uint64 | |
728 SDL_AtomicDecrementThenFetch64(volatile Uint64 * ptr) | |
729 { | |
730 #ifdef nativeDecrementThenFetch64 | |
731 return nativeDecrementThenFetch64(ptr); | |
732 #else | |
733 Uint64 tmp = 0; | |
734 | |
735 privateWaitLock(); | |
736 (*ptr)-= 1; | |
737 tmp = *ptr; | |
738 privateUnlock(); | |
739 | |
740 return tmp; | |
741 #endif | |
742 } | |
743 | |
744 Uint64 | |
745 SDL_AtomicAddThenFetch64(volatile Uint64 * ptr, Uint64 value) | |
746 { | |
747 #ifdef nativeAddThenFetch64 | |
748 return nativeAddThenFetch64(ptr, value); | |
749 #else | |
750 Uint64 tmp = 0; | |
751 | |
752 privateWaitLock(); | |
753 (*ptr)+= value; | |
754 tmp = *ptr; | |
755 privateUnlock(); | |
756 | |
757 return tmp; | |
758 #endif | |
759 } | |
760 | |
761 Uint64 | |
762 SDL_AtomicSubtractThenFetch64(volatile Uint64 * ptr, Uint64 value) | |
763 { | |
764 #ifdef nativeSubtractThenFetch64 | |
765 return nativeSubtractThenFetch64(ptr, value); | |
766 #else | |
767 Uint64 tmp = 0; | |
768 | |
769 privateWaitLock(); | |
770 (*ptr)-= value; | |
771 tmp = *ptr; | |
772 privateUnlock(); | |
773 | |
774 return tmp; | |
775 #endif | |
776 } | |
777 #endif | |
778 | |
779 /* QNX native 32 bit atomic operations */ | |
780 | |
781 Uint32 | |
782 SDL_AtomicExchange32(volatile Uint32 * ptr, Uint32 value) | |
783 { | |
784 Uint32 tmp = 0; | |
785 | |
786 privateWaitLock(); | |
787 tmp = *ptr; | |
788 *ptr = value; | |
789 privateUnlock(); | |
790 | |
791 return tmp; | |
792 } | |
793 | |
794 SDL_bool | |
795 SDL_AtomicCompareThenSet32(volatile Uint32 * ptr, Uint32 oldvalue, Uint32 newvalue) | |
796 { | |
797 SDL_bool result = SDL_FALSE; | |
798 | |
799 privateWaitLock(); | |
800 result = (*ptr == oldvalue); | |
801 if (result) | |
802 { | |
803 *ptr = newvalue; | |
804 } | |
805 privateUnlock(); | |
806 | |
807 return result; | |
808 } | |
809 | |
810 SDL_bool | |
811 SDL_AtomicTestThenSet32(volatile Uint32 * ptr) | |
812 { | |
813 SDL_bool result = SDL_FALSE; | |
814 | |
815 privateWaitLock(); | |
816 result = (*ptr == 0); | |
817 if (result) | |
818 { | |
819 *ptr = 1; | |
820 } | |
821 privateUnlock(); | |
822 | |
823 return result; | |
824 } | |
825 | |
826 void | |
827 SDL_AtomicClear32(volatile Uint32 * ptr) | |
828 { | |
829 atomic_clr(ptr, 0xFFFFFFFF); | |
830 } | |
831 | |
832 Uint32 | |
833 SDL_AtomicFetchThenIncrement32(volatile Uint32 * ptr) | |
834 { | |
835 return atomic_add_value(ptr, 0x00000001); | |
836 } | |
837 | |
838 Uint32 | |
839 SDL_AtomicFetchThenDecrement32(volatile Uint32 * ptr) | |
840 { | |
841 return atomic_sub_value(ptr, 0x00000001); | |
842 } | |
843 | |
844 Uint32 | |
845 SDL_AtomicFetchThenAdd32(volatile Uint32 * ptr, Uint32 value) | |
846 { | |
847 return atomic_add_value(ptr, value); | |
848 } | |
849 | |
850 Uint32 | |
851 SDL_AtomicFetchThenSubtract32(volatile Uint32 * ptr, Uint32 value) | |
852 { | |
853 return atomic_sub_value(ptr, value); | |
854 } | |
855 | |
856 Uint32 | |
857 SDL_AtomicIncrementThenFetch32(volatile Uint32 * ptr) | |
858 { | |
859 atomic_add(ptr, 0x00000001); | |
860 return atomic_add_value(ptr, 0x00000000); | |
861 } | |
862 | |
863 Uint32 | |
864 SDL_AtomicDecrementThenFetch32(volatile Uint32 * ptr) | |
865 { | |
866 atomic_sub(ptr, 0x00000001); | |
867 return atomic_sub_value(ptr, 0x00000000); | |
868 } | |
869 | |
870 Uint32 | |
871 SDL_AtomicAddThenFetch32(volatile Uint32 * ptr, Uint32 value) | |
872 { | |
873 atomic_add(ptr, value); | |
874 return atomic_add_value(ptr, 0x00000000); | |
875 } | |
876 | |
877 Uint32 | |
878 SDL_AtomicSubtractThenFetch32(volatile Uint32 * ptr, Uint32 value) | |
879 { | |
880 atomic_sub(ptr, value); | |
881 return atomic_sub_value(ptr, 0x00000000); | |
882 } |