comparison 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
comparison
equal deleted inserted replaced
5003:3a95a2b93eb3 5004:0c72ae7b7cb2
42 return (InterlockedExchange(lock, 1) == 0); 42 return (InterlockedExchange(lock, 1) == 0);
43 43
44 #elif defined(__MACOSX__) 44 #elif defined(__MACOSX__)
45 return OSAtomicCompareAndSwap32Barrier(0, 1, lock); 45 return OSAtomicCompareAndSwap32Barrier(0, 1, lock);
46 46
47 #elif defined(__GNUC__) 47 #elif defined(HAVE_GCC_ATOMICS)
48 #if defined(__arm__) 48 return (__sync_lock_test_and_set(lock, 1) == 0);
49 #ifdef __ARM_ARCH_5__ 49
50 #elif defined(__GNUC__) && defined(__arm__) && defined(__ARM_ARCH_5__)
50 int result; 51 int result;
51 __asm__ __volatile__ ( 52 __asm__ __volatile__ (
52 "swp %0, %1, [%2]\n" 53 "swp %0, %1, [%2]\n"
53 : "=&r,&r" (result) : "r,0" (1), "r,r" (lock) : "memory"); 54 : "=&r,&r" (result) : "r,0" (1), "r,r" (lock) : "memory");
54 return (result == 0); 55 return (result == 0);
55 #else 56
57 #elif defined(__GNUC__) && defined(__arm__)
56 int result; 58 int result;
57 __asm__ __volatile__ ( 59 __asm__ __volatile__ (
58 "ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]" 60 "ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]"
59 : "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory"); 61 : "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory");
60 return (result == 0); 62 return (result == 0);
61 #endif
62 #else
63 return (__sync_lock_test_and_set(lock, 1) == 0);
64 #endif
65 63
66 #else 64 #else
67 /* Need CPU instructions for spinlock here! */ 65 /* Need CPU instructions for spinlock here! */
68 __need_spinlock_implementation__ 66 __need_spinlock_implementation__
69 #endif 67 #endif
79 } 77 }
80 78
81 void 79 void
82 SDL_AtomicUnlock(SDL_SpinLock *lock) 80 SDL_AtomicUnlock(SDL_SpinLock *lock)
83 { 81 {
84 #if defined(__WIN32__) 82 /* Assuming atomic assignment operation and full memory barrier in lock */
85 *lock = 0; 83 *lock = 0;
86
87 #elif defined(__MACOSX__)
88 *lock = 0;
89
90 #elif defined(__GNUC__) && !defined(__arm__)
91 __sync_lock_release(lock);
92
93 #else
94 /* Assuming memory barrier in lock and integral assignment operation */
95 *lock = 0;
96 #endif
97 } 84 }
98 85
99 /* vi: set ts=4 sw=4 expandtab: */ 86 /* vi: set ts=4 sw=4 expandtab: */