Mercurial > sdl-ios-xcode
annotate src/atomic/SDL_spinlock.c @ 5004:0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Changed the CAS return value to bool, so it's efficient with OSAtomicCompareAndSwap32Barrier()
Added an atomic test adapted from code by Michael Davidsaver
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 16 Jan 2011 15:16:39 -0800 |
parents | 3a95a2b93eb3 |
children | 1bf9e38431ec |
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 #include "SDL_timer.h" |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
26 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
27 #if defined(__WIN32__) |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
28 #define WIN32_LEAN_AND_MEAN |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
29 #include <windows.h> |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
30 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
31 #elif defined(__MACOSX__) |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
32 #include <libkern/OSAtomic.h> |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
33 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
34 #endif |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
35 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
36 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
37 /* This function is where all the magic happens... */ |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
38 SDL_bool |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
39 SDL_AtomicTryLock(SDL_SpinLock *lock) |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
40 { |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
41 #if defined(__WIN32__) |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
42 return (InterlockedExchange(lock, 1) == 0); |
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 #elif defined(__MACOSX__) |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
45 return OSAtomicCompareAndSwap32Barrier(0, 1, lock); |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
46 |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
47 #elif defined(HAVE_GCC_ATOMICS) |
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
48 return (__sync_lock_test_and_set(lock, 1) == 0); |
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
49 |
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
50 #elif defined(__GNUC__) && defined(__arm__) && defined(__ARM_ARCH_5__) |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
51 int result; |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
52 __asm__ __volatile__ ( |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
53 "swp %0, %1, [%2]\n" |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
54 : "=&r,&r" (result) : "r,0" (1), "r,r" (lock) : "memory"); |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
55 return (result == 0); |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
56 |
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
57 #elif defined(__GNUC__) && defined(__arm__) |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
58 int result; |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
59 __asm__ __volatile__ ( |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
60 "ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]" |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
61 : "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory"); |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
62 return (result == 0); |
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 #else |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
65 /* Need CPU instructions for spinlock here! */ |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
66 __need_spinlock_implementation__ |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
67 #endif |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
68 } |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
69 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
70 void |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
71 SDL_AtomicLock(SDL_SpinLock *lock) |
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 /* FIXME: Should we have an eventual timeout? */ |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
74 while (!SDL_AtomicTryLock(lock)) { |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
75 SDL_Delay(0); |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
76 } |
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 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
79 void |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
80 SDL_AtomicUnlock(SDL_SpinLock *lock) |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
81 { |
5004
0c72ae7b7cb2
Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents:
5003
diff
changeset
|
82 /* Assuming atomic assignment operation and full memory barrier in lock */ |
5003
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
83 *lock = 0; |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
84 } |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
85 |
3a95a2b93eb3
Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
86 /* vi: set ts=4 sw=4 expandtab: */ |