annotate src/atomic/SDL_atomic.c @ 5097:dceec93471e7

Improvements based on feedback from Anthony Williams
author Sam Lantinga <slouken@libsdl.org>
date Tue, 25 Jan 2011 17:40:06 -0800
parents 0c72ae7b7cb2
children b530ef003506
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
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
3 Copyright (C) 1997-2010 Sam Lantinga
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: */