comparison include/SDL_atomic.h @ 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 3e1bf2b8bd81
children 48a80f2a7ff2
comparison
equal deleted inserted replaced
3201:c297230efc75 3202:3aa519a5c676
26 * Atomic operations. 26 * Atomic operations.
27 */ 27 */
28 28
29 #ifndef _SDL_atomic_h_ 29 #ifndef _SDL_atomic_h_
30 #define _SDL_atomic_h_ 30 #define _SDL_atomic_h_
31
32 31
33 #include "SDL_stdinc.h" 32 #include "SDL_stdinc.h"
34 #include "SDL_platform.h" 33 #include "SDL_platform.h"
35 34
36 #include "begin_code.h" 35 #include "begin_code.h"
40 /* *INDENT-OFF* */ 39 /* *INDENT-OFF* */
41 extern "C" { 40 extern "C" {
42 /* *INDENT-ON* */ 41 /* *INDENT-ON* */
43 #endif 42 #endif
44 43
45 /* *INDENT-OFF* */ 44 /**
46 /** 45 * These operations may, or may not, actually be implemented using
47 * \def SDL_AtomicBusyWait32 (ptr) 46 * processor specific atomic operations. When possible they are
48 * 47 * implemented as true processor specific atomic operations. When that
49 * \brief Implements a simple busy wait for use with 48 * is not possible the are implemented using locks that *do* use the
50 * SDL_AtomicTestThenSet and SDL_AtomicClear. 49 * available atomic operations. In rare cases they may be implemented
51 * 50 * using SDL's mutex fuctions.
52 * Note: This can be an infinite loop. 51 */
53 *
54 */
55 #define SDL_AtomicBusyWait32(ptr) \
56 { \
57 while (!SDL_AtomicTestThenSet32(ptr) \
58 { \
59 }; \
60 };
61
62 /**
63 * \def SDL_AtomicWait32(ptr)
64 *
65 * \brief A safer way to wait for a test-then-set lock to be cleared.
66 *
67 * This assumes that the SDL_Sleep(0) call acts as a thread_yeild
68 * operation.
69 *
70 */
71 #define SDL_AtomicWait32(ptr) \
72 { \
73 while (!SDL_AtomicTestThenSet32(ptr) \
74 { \
75 SDL_Sleep(0); \
76 }; \
77 };
78
79 /**
80 * \def SDL_AtomicBusyWait64(ptr)
81 *
82 * \brief 64 bit version of busy wait
83 *
84 * \sa SDL_AtomicBusyWait32
85 */
86 #define SDL_AtomicBusyWait64(ptr) \
87 { \
88 while (!SDL_AtomicTestThenSet64(ptr) \
89 { \
90 }; \
91 };
92
93 /**
94 * \def SDL_AtomicWait64(ptr)
95 *
96 * \brief 64 bit version of SDL_AtomicWait32
97 *
98 * \sa SDL_AtomicWait32
99 */
100 #define SDL_AtomicWait64(ptr) \
101 { \
102 while (!SDL_AtomicTestThenSet64(ptr) \
103 { \
104 SDL_Sleep(0); \
105 }; \
106 };
107 /* *INDENT-ON* */
108 52
109 /* Function prototypes */ 53 /* Function prototypes */
54
55 /* 8 bit atomic operations */
56
57 extern DECLSPEC Uint8 SDLCALL SDL_AtomicExchange8(Uint8 * ptr, Uint8 value);
58 extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCompareThenSet8(Uint8 * ptr,
59 Uint8 oldvalue, Uint8 newvalue);
60 extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTestThenSet8(Uint8 * ptr);
61 extern DECLSPEC void SDLCALL SDL_AtomicClear8(Uint8 * ptr);
62 extern DECLSPEC Uint8 SDLCALL SDL_AtomicFetchThenIncrement8(Uint8 * ptr);
63 extern DECLSPEC Uint8 SDLCALL SDL_AtomicFetchThenDecrement8(Uint8 * ptr);
64 extern DECLSPEC Uint8 SDLCALL SDL_AtomicFetchThenAdd8(Uint8 * ptr, Uint8 value);
65 extern DECLSPEC Uint8 SDLCALL SDL_AtomicFetchThenSubtract8(Uint8 * ptr, Uint8 value);
66 extern DECLSPEC Uint8 SDLCALL SDL_AtomicIncrementThenFetch8(Uint8 * ptr);
67 extern DECLSPEC Uint8 SDLCALL SDL_AtomicDecrementThenFetch8(Uint8 * ptr);
68 extern DECLSPEC Uint8 SDLCALL SDL_AtomicAddThenFetch8(Uint8 * ptr, Uint8 value);
69 extern DECLSPEC Uint8 SDLCALL SDL_AtomicSubtractThenFetch8(Uint8 * ptr, Uint8 value);
70
71 /* 16 bit atomic operations */
72
73 extern DECLSPEC Uint16 SDLCALL SDL_AtomicExchange16(Uint16 * ptr, Uint16 value);
74 extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCompareThenSet16(Uint16 * ptr,
75 Uint16 oldvalue, Uint16 newvalue);
76 extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTestThenSet16(Uint16 * ptr);
77 extern DECLSPEC void SDLCALL SDL_AtomicClear16(Uint16 * ptr);
78 extern DECLSPEC Uint16 SDLCALL SDL_AtomicFetchThenIncrement16(Uint16 * ptr);
79 extern DECLSPEC Uint16 SDLCALL SDL_AtomicFetchThenDecrement16(Uint16 * ptr);
80 extern DECLSPEC Uint16 SDLCALL SDL_AtomicFetchThenAdd16(Uint16 * ptr, Uint16 value);
81 extern DECLSPEC Uint16 SDLCALL SDL_AtomicFetchThenSubtract16(Uint16 * ptr, Uint16 value);
82 extern DECLSPEC Uint16 SDLCALL SDL_AtomicIncrementThenFetch16(Uint16 * ptr);
83 extern DECLSPEC Uint16 SDLCALL SDL_AtomicDecrementThenFetch16(Uint16 * ptr);
84 extern DECLSPEC Uint16 SDLCALL SDL_AtomicAddThenFetch16(Uint16 * ptr, Uint16 value);
85 extern DECLSPEC Uint16 SDLCALL SDL_AtomicSubtractThenFetch16(Uint16 * ptr, Uint16 value);
86
87 /* 32 bit atomic operations */
110 88
111 /** 89 /**
112 * \fn int SDL_AtomicExchange32(Uint32 * ptr, Uint32 value) 90 * \fn int SDL_AtomicExchange32(Uint32 * ptr, Uint32 value)
113 * 91 *
114 * \brief Atomically exchange two 32 bit values. 92 * \brief Atomically exchange two 32 bit values.
250 * \param value The value to be subtracted. 228 * \param value The value to be subtracted.
251 * 229 *
252 */ 230 */
253 extern DECLSPEC Uint32 SDLCALL SDL_AtomicSubtractThenFetch32(Uint32 * ptr, Uint32 value); 231 extern DECLSPEC Uint32 SDLCALL SDL_AtomicSubtractThenFetch32(Uint32 * ptr, Uint32 value);
254 232
233 /* 64 bit atomic operations */
255 #ifdef SDL_HAS_64BIT_TYPE 234 #ifdef SDL_HAS_64BIT_TYPE
256 235
257 extern DECLSPEC Uint64 SDLCALL SDL_AtomicExchange64(Uint64 * ptr, Uint64 value); 236 extern DECLSPEC Uint64 SDLCALL SDL_AtomicExchange64(Uint64 * ptr, Uint64 value);
258 extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCompareThenSet64(Uint64 * ptr, 237 extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCompareThenSet64(Uint64 * ptr,
259 Uint64 oldvalue, Uint64 newvalue); 238 Uint64 oldvalue, Uint64 newvalue);
265 extern DECLSPEC Uint64 SDLCALL SDL_AtomicFetchThenSubtract64(Uint64 * ptr, Uint64 value); 244 extern DECLSPEC Uint64 SDLCALL SDL_AtomicFetchThenSubtract64(Uint64 * ptr, Uint64 value);
266 extern DECLSPEC Uint64 SDLCALL SDL_AtomicIncrementThenFetch64(Uint64 * ptr); 245 extern DECLSPEC Uint64 SDLCALL SDL_AtomicIncrementThenFetch64(Uint64 * ptr);
267 extern DECLSPEC Uint64 SDLCALL SDL_AtomicDecrementThenFetch64(Uint64 * ptr); 246 extern DECLSPEC Uint64 SDLCALL SDL_AtomicDecrementThenFetch64(Uint64 * ptr);
268 extern DECLSPEC Uint64 SDLCALL SDL_AtomicAddThenFetch64(Uint64 * ptr, Uint64 value); 247 extern DECLSPEC Uint64 SDLCALL SDL_AtomicAddThenFetch64(Uint64 * ptr, Uint64 value);
269 extern DECLSPEC Uint64 SDLCALL SDL_AtomicSubtractThenFetch64(Uint64 * ptr, Uint64 value); 248 extern DECLSPEC Uint64 SDLCALL SDL_AtomicSubtractThenFetch64(Uint64 * ptr, Uint64 value);
270 #endif 249 #endif /* SDL_HAS_64BIT_TYPE */
271 250
272 /* Ends C function definitions when using C++ */ 251 /* Ends C function definitions when using C++ */
273 #ifdef __cplusplus 252 #ifdef __cplusplus
274 /* *INDENT-OFF* */ 253 /* *INDENT-OFF* */
275 } 254 }