Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
495 lines (409 loc) · 9.62 KB

SDL_atomic.c

File metadata and controls

495 lines (409 loc) · 9.62 KB
 
Sep 17, 2009
Sep 17, 2009
2
3
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2009 Sam Lantinga
Sep 17, 2009
Sep 17, 2009
5
6
7
8
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
Sep 17, 2009
Sep 17, 2009
10
11
12
13
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
Sep 17, 2009
Sep 17, 2009
15
16
17
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sep 17, 2009
Sep 17, 2009
19
20
21
22
Sam Lantinga
slouken@libsdl.org
Contributed by Bob Pendleton, bob@pendleton.com
Jun 29, 2009
Jun 29, 2009
25
#include "SDL_stdinc.h"
26
27
#include "SDL_atomic.h"
Sep 17, 2009
Sep 17, 2009
28
29
#include "SDL_error.h"
Jun 29, 2009
Jun 29, 2009
30
/*
Sep 17, 2009
Sep 17, 2009
31
This file provides 32, and 64 bit atomic operations. If the
Jun 29, 2009
Jun 29, 2009
32
33
operations are provided by the native hardware and operating system
they are used. If they are not then the operations are emulated
Sep 17, 2009
Sep 17, 2009
34
35
using the SDL spin lock operations. If spin lock can not be
implemented then these functions must fail.
Jun 29, 2009
Jun 29, 2009
36
37
38
*/
/*
Sep 17, 2009
Sep 17, 2009
39
LINUX/GCC VERSION.
Jun 29, 2009
Jun 29, 2009
40
Sep 17, 2009
Sep 17, 2009
41
42
43
44
This version of the code assumes support of the atomic builtins as
documented at gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html This
code should work on any modern x86 or other processor supported by
GCC.
Jun 29, 2009
Jun 29, 2009
45
Sep 17, 2009
Sep 17, 2009
46
47
48
Some processors will only support some of these operations so
#ifdefs will have to be added as incompatibilities are discovered
*/
Jun 29, 2009
Jun 29, 2009
49
Sep 17, 2009
Sep 17, 2009
50
51
52
/*
Native spinlock routines.
*/
Jun 29, 2009
Jun 29, 2009
53
Sep 17, 2009
Sep 17, 2009
54
55
void
SDL_AtomicLock(SDL_SpinLock *lock)
Jun 29, 2009
Jun 29, 2009
56
{
Sep 17, 2009
Sep 17, 2009
57
while (0 != __sync_lock_test_and_set(lock, 1))
Jun 29, 2009
Jun 29, 2009
58
59
60
61
{
}
}
Sep 17, 2009
Sep 17, 2009
62
63
void
SDL_AtomicUnlock(SDL_SpinLock *lock)
Jun 29, 2009
Jun 29, 2009
64
{
Sep 17, 2009
Sep 17, 2009
65
__sync_lock_test_and_set(lock, 0);
Jun 29, 2009
Jun 29, 2009
66
67
}
Sep 17, 2009
Sep 17, 2009
68
69
70
71
72
/*
Note that platform specific versions can be built from this version
by changing the #undefs to #defines and adding platform specific
code.
*/
Jun 29, 2009
Jun 29, 2009
73
Sep 17, 2009
Sep 17, 2009
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#define nativeTestThenSet32
#define nativeClear32
#define nativeFetchThenIncrement32
#define nativeFetchThenDecrement32
#define nativeFetchThenAdd32
#define nativeFetchThenSubtract32
#define nativeIncrementThenFetch32
#define nativeDecrementThenFetch32
#define nativeAddThenFetch32
#define nativeSubtractThenFetch32
#define nativeTestThenSet64
#define nativeClear64
#define nativeFetchThenIncrement64
#define nativeFetchThenDecrement64
#define nativeFetchThenAdd64
#define nativeFetchThenSubtract64
#define nativeIncrementThenFetch64
#define nativeDecrementThenFetch64
#define nativeAddThenFetch64
#define nativeSubtractThenFetch64
Jun 29, 2009
Jun 29, 2009
95
Sep 17, 2009
Sep 17, 2009
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
If any of the operations are not provided then we must emulate some
of them. That means we need a nice implementation of spin locks
that avoids the "one big lock" problem. We use a vector of spin
locks and pick which one to use based on the address of the operand
of the function.
To generate the index of the lock we first shift by 3 bits to get
rid on the zero bits that result from 32 and 64 bit allignment of
data. We then mask off all but 5 bits and use those 5 bits as an
index into the table.
Picking the lock this way insures that accesses to the same data at
the same time will go to the same lock. OTOH, accesses to different
data have only a 1/32 chance of hitting the same lock. That should
pretty much eliminate the chances of several atomic operations on
different data from waiting on the same "big lock". If it isn't
then the table of locks can be expanded to a new size so long as
the new size if a power of two.
*/
Jun 29, 2009
Jun 29, 2009
116
Sep 17, 2009
Sep 17, 2009
117
118
119
120
121
122
static SDL_SpinLock locks[32] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
Jun 29, 2009
Jun 29, 2009
123
Sep 17, 2009
Sep 17, 2009
124
125
static __inline__ void
privateWaitLock(volatile void *ptr)
Jun 29, 2009
Jun 29, 2009
126
{
Sep 17, 2009
Sep 17, 2009
127
128
129
130
#if SIZEOF_VOIDP == 4
Uint32 index = ((((Uint32)ptr) >> 3) & 0x1f);
#elif SIZEOF_VOIDP == 8
Uint64 index = ((((Uint64)ptr) >> 3) & 0x1f);
Jun 29, 2009
Jun 29, 2009
131
132
#endif
Sep 17, 2009
Sep 17, 2009
133
SDL_AtomicLock(&locks[index]);
Jun 29, 2009
Jun 29, 2009
134
135
}
Sep 17, 2009
Sep 17, 2009
136
137
static __inline__ void
privateUnlock(volatile void *ptr)
Jun 29, 2009
Jun 29, 2009
138
{
Sep 17, 2009
Sep 17, 2009
139
140
141
142
#if SIZEOF_VOIDP == 4
Uint32 index = ((((Uint32)ptr) >> 3) & 0x1f);
#elif SIZEOF_VOIDP == 8
Uint64 index = ((((Uint64)ptr) >> 3) & 0x1f);
Jun 29, 2009
Jun 29, 2009
143
144
#endif
Sep 17, 2009
Sep 17, 2009
145
SDL_AtomicUnlock(&locks[index]);
Jun 29, 2009
Jun 29, 2009
146
147
148
149
}
/* 32 bit atomic operations */
Jul 9, 2009
Jul 9, 2009
151
SDL_AtomicTestThenSet32(volatile Uint32 * ptr)
Jun 29, 2009
Jun 29, 2009
153
#ifdef nativeTestThenSet32
Sep 17, 2009
Sep 17, 2009
154
return 0 == __sync_lock_test_and_set(ptr, 1);
Jun 29, 2009
Jun 29, 2009
155
156
157
#else
SDL_bool result = SDL_FALSE;
Sep 17, 2009
Sep 17, 2009
158
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
159
160
161
162
163
result = (*ptr == 0);
if (result)
{
*ptr = 1;
}
Sep 17, 2009
Sep 17, 2009
164
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
165
166
167
return result;
#endif
Jul 9, 2009
Jul 9, 2009
171
SDL_AtomicClear32(volatile Uint32 * ptr)
Jun 29, 2009
Jun 29, 2009
173
#ifdef nativeClear32
Sep 17, 2009
Sep 17, 2009
174
175
__sync_lock_test_and_set(ptr, 0);
return;
Jun 29, 2009
Jun 29, 2009
176
#else
Sep 17, 2009
Sep 17, 2009
177
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
178
*ptr = 0;
Sep 17, 2009
Sep 17, 2009
179
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
180
181
182
return;
#endif
Jul 9, 2009
Jul 9, 2009
186
SDL_AtomicFetchThenIncrement32(volatile Uint32 * ptr)
Jun 29, 2009
Jun 29, 2009
188
#ifdef nativeFetchThenIncrement32
Sep 17, 2009
Sep 17, 2009
189
return __sync_fetch_and_add(ptr, 1);
Jun 29, 2009
Jun 29, 2009
190
#else
Jul 2, 2009
Jul 2, 2009
191
Uint32 tmp = 0;
Jun 29, 2009
Jun 29, 2009
192
Sep 17, 2009
Sep 17, 2009
193
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
194
195
tmp = *ptr;
(*ptr)+= 1;
Sep 17, 2009
Sep 17, 2009
196
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
197
198
199
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
203
SDL_AtomicFetchThenDecrement32(volatile Uint32 * ptr)
Jun 29, 2009
Jun 29, 2009
205
#ifdef nativeFetchThenDecrement32
Sep 17, 2009
Sep 17, 2009
206
return __sync_fetch_and_sub(ptr, 1);
Jun 29, 2009
Jun 29, 2009
207
#else
Jul 2, 2009
Jul 2, 2009
208
Uint32 tmp = 0;
Jun 29, 2009
Jun 29, 2009
209
Sep 17, 2009
Sep 17, 2009
210
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
211
212
tmp = *ptr;
(*ptr) -= 1;
Sep 17, 2009
Sep 17, 2009
213
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
214
215
216
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
220
SDL_AtomicFetchThenAdd32(volatile Uint32 * ptr, Uint32 value)
Jun 29, 2009
Jun 29, 2009
222
#ifdef nativeFetchThenAdd32
Sep 17, 2009
Sep 17, 2009
223
return __sync_fetch_and_add(ptr, value);
Jun 29, 2009
Jun 29, 2009
224
#else
Jul 2, 2009
Jul 2, 2009
225
Uint32 tmp = 0;
Jun 29, 2009
Jun 29, 2009
226
Sep 17, 2009
Sep 17, 2009
227
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
228
229
tmp = *ptr;
(*ptr)+= value;
Sep 17, 2009
Sep 17, 2009
230
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
231
232
233
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
237
SDL_AtomicFetchThenSubtract32(volatile Uint32 * ptr, Uint32 value)
Jun 29, 2009
Jun 29, 2009
239
#ifdef nativeFetchThenSubtract32
Sep 17, 2009
Sep 17, 2009
240
return __sync_fetch_and_sub(ptr, value);
Jun 29, 2009
Jun 29, 2009
241
#else
Jul 2, 2009
Jul 2, 2009
242
Uint32 tmp = 0;
Jun 29, 2009
Jun 29, 2009
243
Sep 17, 2009
Sep 17, 2009
244
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
245
246
tmp = *ptr;
(*ptr)-= value;
Sep 17, 2009
Sep 17, 2009
247
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
248
249
250
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
254
SDL_AtomicIncrementThenFetch32(volatile Uint32 * ptr)
Jun 29, 2009
Jun 29, 2009
256
#ifdef nativeIncrementThenFetch32
Sep 17, 2009
Sep 17, 2009
257
return __sync_add_and_fetch(ptr, 1);
Jun 29, 2009
Jun 29, 2009
258
#else
Jul 2, 2009
Jul 2, 2009
259
Uint32 tmp = 0;
Jun 29, 2009
Jun 29, 2009
260
Sep 17, 2009
Sep 17, 2009
261
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
262
263
(*ptr)+= 1;
tmp = *ptr;
Sep 17, 2009
Sep 17, 2009
264
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
265
266
267
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
271
SDL_AtomicDecrementThenFetch32(volatile Uint32 * ptr)
Jun 29, 2009
Jun 29, 2009
273
#ifdef nativeDecrementThenFetch32
Sep 17, 2009
Sep 17, 2009
274
return __sync_sub_and_fetch(ptr, 1);
Jun 29, 2009
Jun 29, 2009
275
#else
Jul 2, 2009
Jul 2, 2009
276
Uint32 tmp = 0;
Jun 29, 2009
Jun 29, 2009
277
Sep 17, 2009
Sep 17, 2009
278
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
279
280
(*ptr)-= 1;
tmp = *ptr;
Sep 17, 2009
Sep 17, 2009
281
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
282
283
284
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
288
SDL_AtomicAddThenFetch32(volatile Uint32 * ptr, Uint32 value)
Jun 29, 2009
Jun 29, 2009
290
#ifdef nativeAddThenFetch32
Sep 17, 2009
Sep 17, 2009
291
return __sync_add_and_fetch(ptr, value);
Jun 29, 2009
Jun 29, 2009
292
#else
Jul 2, 2009
Jul 2, 2009
293
Uint32 tmp = 0;
Jun 29, 2009
Jun 29, 2009
294
Sep 17, 2009
Sep 17, 2009
295
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
296
297
(*ptr)+= value;
tmp = *ptr;
Sep 17, 2009
Sep 17, 2009
298
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
299
300
301
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
305
SDL_AtomicSubtractThenFetch32(volatile Uint32 * ptr, Uint32 value)
Jun 29, 2009
Jun 29, 2009
307
#ifdef nativeSubtractThenFetch32
Sep 17, 2009
Sep 17, 2009
308
return __sync_sub_and_fetch(ptr, value);
Jun 29, 2009
Jun 29, 2009
309
#else
Jul 2, 2009
Jul 2, 2009
310
Uint32 tmp = 0;
Jun 29, 2009
Jun 29, 2009
311
Sep 17, 2009
Sep 17, 2009
312
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
313
314
(*ptr)-= value;
tmp = *ptr;
Sep 17, 2009
Sep 17, 2009
315
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
316
317
318
return tmp;
#endif
Jun 29, 2009
Jun 29, 2009
321
322
/* 64 bit atomic operations */
#ifdef SDL_HAS_64BIT_TYPE
Jul 9, 2009
Jul 9, 2009
325
SDL_AtomicTestThenSet64(volatile Uint64 * ptr)
Jun 29, 2009
Jun 29, 2009
327
#ifdef nativeTestThenSet64
Sep 17, 2009
Sep 17, 2009
328
return 0 == __sync_lock_test_and_set(ptr, 1);
Jun 29, 2009
Jun 29, 2009
329
330
331
#else
SDL_bool result = SDL_FALSE;
Sep 17, 2009
Sep 17, 2009
332
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
333
334
335
336
337
result = (*ptr == 0);
if (result)
{
*ptr = 1;
}
Sep 17, 2009
Sep 17, 2009
338
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
339
340
341
return result;
#endif
Jul 9, 2009
Jul 9, 2009
345
SDL_AtomicClear64(volatile Uint64 * ptr)
Jun 29, 2009
Jun 29, 2009
347
#ifdef nativeClear64
Sep 17, 2009
Sep 17, 2009
348
349
__sync_lock_test_and_set(ptr, 0);
return;
Jun 29, 2009
Jun 29, 2009
350
#else
Sep 17, 2009
Sep 17, 2009
351
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
352
*ptr = 0;
Sep 17, 2009
Sep 17, 2009
353
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
354
355
356
return;
#endif
Jul 9, 2009
Jul 9, 2009
360
SDL_AtomicFetchThenIncrement64(volatile Uint64 * ptr)
Jun 29, 2009
Jun 29, 2009
362
#ifdef nativeFetchThenIncrement64
Sep 17, 2009
Sep 17, 2009
363
return __sync_fetch_and_add(ptr, 1);
Jun 29, 2009
Jun 29, 2009
364
#else
Jul 2, 2009
Jul 2, 2009
365
Uint64 tmp = 0;
Jun 29, 2009
Jun 29, 2009
366
Sep 17, 2009
Sep 17, 2009
367
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
368
369
tmp = *ptr;
(*ptr)+= 1;
Sep 17, 2009
Sep 17, 2009
370
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
371
372
373
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
377
SDL_AtomicFetchThenDecrement64(volatile Uint64 * ptr)
Jun 29, 2009
Jun 29, 2009
379
#ifdef nativeFetchThenDecrement64
Sep 17, 2009
Sep 17, 2009
380
return __sync_fetch_and_sub(ptr, 1);
Jun 29, 2009
Jun 29, 2009
381
#else
Jul 2, 2009
Jul 2, 2009
382
Uint64 tmp = 0;
Jun 29, 2009
Jun 29, 2009
383
Sep 17, 2009
Sep 17, 2009
384
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
385
386
tmp = *ptr;
(*ptr) -= 1;
Sep 17, 2009
Sep 17, 2009
387
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
388
389
390
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
394
SDL_AtomicFetchThenAdd64(volatile Uint64 * ptr, Uint64 value)
Jun 29, 2009
Jun 29, 2009
396
#ifdef nativeFetchThenAdd64
Sep 17, 2009
Sep 17, 2009
397
return __sync_fetch_and_add(ptr, value);
Jun 29, 2009
Jun 29, 2009
398
#else
Jul 2, 2009
Jul 2, 2009
399
Uint64 tmp = 0;
Jun 29, 2009
Jun 29, 2009
400
Sep 17, 2009
Sep 17, 2009
401
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
402
403
tmp = *ptr;
(*ptr)+= value;
Sep 17, 2009
Sep 17, 2009
404
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
405
406
407
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
411
SDL_AtomicFetchThenSubtract64(volatile Uint64 * ptr, Uint64 value)
Jun 29, 2009
Jun 29, 2009
413
#ifdef nativeFetchThenSubtract64
Sep 17, 2009
Sep 17, 2009
414
return __sync_fetch_and_sub(ptr, value);
Jun 29, 2009
Jun 29, 2009
415
#else
Jul 2, 2009
Jul 2, 2009
416
Uint64 tmp = 0;
Jun 29, 2009
Jun 29, 2009
417
Sep 17, 2009
Sep 17, 2009
418
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
419
420
tmp = *ptr;
(*ptr)-= value;
Sep 17, 2009
Sep 17, 2009
421
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
422
423
424
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
428
SDL_AtomicIncrementThenFetch64(volatile Uint64 * ptr)
Jun 29, 2009
Jun 29, 2009
430
#ifdef nativeIncrementThenFetch64
Sep 17, 2009
Sep 17, 2009
431
return __sync_add_and_fetch(ptr, 1);
Jun 29, 2009
Jun 29, 2009
432
#else
Jul 2, 2009
Jul 2, 2009
433
Uint64 tmp = 0;
Jun 29, 2009
Jun 29, 2009
434
Sep 17, 2009
Sep 17, 2009
435
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
436
437
(*ptr)+= 1;
tmp = *ptr;
Sep 17, 2009
Sep 17, 2009
438
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
439
440
441
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
445
SDL_AtomicDecrementThenFetch64(volatile Uint64 * ptr)
Jun 29, 2009
Jun 29, 2009
447
#ifdef nativeDecrementThenFetch64
Sep 17, 2009
Sep 17, 2009
448
return __sync_sub_and_fetch(ptr, 1);
Jun 29, 2009
Jun 29, 2009
449
#else
Jul 2, 2009
Jul 2, 2009
450
Uint64 tmp = 0;
Jun 29, 2009
Jun 29, 2009
451
Sep 17, 2009
Sep 17, 2009
452
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
453
454
(*ptr)-= 1;
tmp = *ptr;
Sep 17, 2009
Sep 17, 2009
455
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
456
457
458
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
462
SDL_AtomicAddThenFetch64(volatile Uint64 * ptr, Uint64 value)
Jun 29, 2009
Jun 29, 2009
464
#ifdef nativeAddThenFetch64
Sep 17, 2009
Sep 17, 2009
465
return __sync_add_and_fetch(ptr, value);
Jun 29, 2009
Jun 29, 2009
466
#else
Jul 2, 2009
Jul 2, 2009
467
Uint64 tmp = 0;
Jun 29, 2009
Jun 29, 2009
468
Sep 17, 2009
Sep 17, 2009
469
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
470
471
(*ptr)+= value;
tmp = *ptr;
Sep 17, 2009
Sep 17, 2009
472
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
473
474
475
return tmp;
#endif
Jul 9, 2009
Jul 9, 2009
479
SDL_AtomicSubtractThenFetch64(volatile Uint64 * ptr, Uint64 value)
Jun 29, 2009
Jun 29, 2009
481
#ifdef nativeSubtractThenFetch64
Sep 17, 2009
Sep 17, 2009
482
return __sync_sub_and_fetch(ptr, value);
Jun 29, 2009
Jun 29, 2009
483
#else
Jul 2, 2009
Jul 2, 2009
484
Uint64 tmp = 0;
Jun 29, 2009
Jun 29, 2009
485
Sep 17, 2009
Sep 17, 2009
486
privateWaitLock(ptr);
Jun 29, 2009
Jun 29, 2009
487
488
(*ptr)-= value;
tmp = *ptr;
Sep 17, 2009
Sep 17, 2009
489
privateUnlock(ptr);
Jun 29, 2009
Jun 29, 2009
490
491
492
return tmp;
#endif
Jun 29, 2009
Jun 29, 2009
494
Sep 17, 2009
Sep 17, 2009
495
#endif /* SDL_HAS_64BIT_TYPE */