Mercurial > sdl-ios-xcode
annotate src/atomic/SDL_atomic.c @ 5267:b530ef003506
Happy 2011! :)
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 11 Feb 2011 22:37:15 -0800 |
parents | dceec93471e7 |
children |
rev | line source |
---|---|
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
1 /* |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
2 SDL - Simple DirectMedia Layer |
5267 | 3 Copyright (C) 1997-2011 Sam Lantinga |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
4 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
5 This library is free software; you can redistribute it and/or |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
7 License as published by the Free Software Foundation; either |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
9 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
10 This library is distributed in the hope that it will be useful, |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
13 Lesser General Public License for more details. |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
14 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
15 You should have received a copy of the GNU Lesser General Public |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
16 License along with this library; if not, write to the Free Software |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
18 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
19 Sam Lantinga |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
20 slouken@libsdl.org |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
21 */ |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
22 #include "SDL_stdinc.h" |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
23 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
24 #include "SDL_atomic.h" |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
25 |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
26 /* Note that we undefine the atomic operations here, in case they are |
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
27 defined as compiler intrinsics while building SDL but the library user |
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
28 doesn't have that compiler. That way we always have a working set of |
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
29 atomic operations built into the library. |
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
30 */ |
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
31 |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
32 /* |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
33 If any of the operations are not provided then we must emulate some |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
34 of them. That means we need a nice implementation of spin locks |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
35 that avoids the "one big lock" problem. We use a vector of spin |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
36 locks and pick which one to use based on the address of the operand |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
37 of the function. |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
38 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
39 To generate the index of the lock we first shift by 3 bits to get |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
40 rid on the zero bits that result from 32 and 64 bit allignment of |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
41 data. We then mask off all but 5 bits and use those 5 bits as an |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
42 index into the table. |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
43 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
44 Picking the lock this way insures that accesses to the same data at |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
45 the same time will go to the same lock. OTOH, accesses to different |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
46 data have only a 1/32 chance of hitting the same lock. That should |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
47 pretty much eliminate the chances of several atomic operations on |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
48 different data from waiting on the same "big lock". If it isn't |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
49 then the table of locks can be expanded to a new size so long as |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
50 the new size is a power of two. |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
51 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
52 Contributed by Bob Pendleton, bob@pendleton.com |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
53 */ |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
54 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
55 static SDL_SpinLock locks[32]; |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
56 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
57 static __inline__ void |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
58 enterLock(void *a) |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
59 { |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
60 uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f); |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
61 |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
62 SDL_AtomicLock(&locks[index]); |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
63 } |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
64 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
65 static __inline__ void |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
66 leaveLock(void *a) |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
67 { |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
68 uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f); |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
69 |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
70 SDL_AtomicUnlock(&locks[index]); |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
71 } |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
72 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
73 SDL_bool |
5097
dceec93471e7
Improvements based on feedback from Anthony Williams
Sam Lantinga <slouken@libsdl.org>
parents:
5004
diff
changeset
|
74 SDL_AtomicCAS_(SDL_atomic_t *a, int oldval, int newval) |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
75 { |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
76 SDL_bool retval = SDL_FALSE; |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
77 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
78 enterLock(a); |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
79 if (a->value == oldval) { |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
80 a->value = newval; |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
81 retval = SDL_TRUE; |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
82 } |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
83 leaveLock(a); |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
84 |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
85 return retval; |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
86 } |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
87 |
5097
dceec93471e7
Improvements based on feedback from Anthony Williams
Sam Lantinga <slouken@libsdl.org>
parents:
5004
diff
changeset
|
88 SDL_bool |
dceec93471e7
Improvements based on feedback from Anthony Williams
Sam Lantinga <slouken@libsdl.org>
parents:
5004
diff
changeset
|
89 SDL_AtomicCASPtr_(void **a, void *oldval, void *newval) |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
90 { |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
91 SDL_bool retval = SDL_FALSE; |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
92 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
93 enterLock(a); |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
94 if (*a == oldval) { |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
95 *a = newval; |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
96 retval = SDL_TRUE; |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
97 } |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
98 leaveLock(a); |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
99 |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
100 return retval; |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
101 } |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
102 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
103 /* vi: set ts=4 sw=4 expandtab: */ |