35 #ifndef _ASTERISK_SPINLOCK_H
36 #define _ASTERISK_SPINLOCK_H
48 AST_SPINLOCK_TYPE_GCC_ATOMICS,
49 AST_SPINLOCK_TYPE_GAS_X86,
50 AST_SPINLOCK_TYPE_GAS_ARM,
51 AST_SPINLOCK_TYPE_GAS_SPARC,
52 AST_SPINLOCK_TYPE_OSX_ATOMICS,
53 AST_SPINLOCK_TYPE_PTHREAD_SPINLOCK,
54 AST_SPINLOCK_TYPE_PTHREAD_MUTEX,
68 #ifdef HAVE_GCC_ATOMICS
69 #define AST_SPINLOCK_TYPE AST_SPINLOCK_TYPE_GCC_ATOMICS
70 #define AST_SPINLOCK_TYPE_LABEL "gcc_atomics"
71 typedef volatile unsigned int ast_spinlock_t;
81 while (__sync_lock_test_and_set(lock, 1)) {
90 return __sync_lock_test_and_set(lock, 1);
95 __sync_lock_release(lock);
112 #if (defined(__x86_64__) || defined(__i386__)) && !defined(AST_SPINLOCK_TYPE)
113 #define AST_SPINLOCK_TYPE AST_SPINLOCK_TYPE_GAS_X86
114 #define AST_SPINLOCK_TYPE_LABEL "gas_x86"
115 typedef volatile unsigned int ast_spinlock_t;
123 static force_inline
int x86chgl(ast_spinlock_t *p,
unsigned int v)
127 :
"+r" (v),
"=m" (*p)
136 while (x86chgl(lock, 1)) {
145 return x86chgl(lock, 1);
167 #if defined(__arm__) && !defined(AST_SPINLOCK_TYPE)
168 #define AST_SPINLOCK_TYPE AST_SPINLOCK_TYPE_GAS_ARM
169 #define AST_SPINLOCK_TYPE_LABEL "gas_arm"
170 typedef volatile unsigned int ast_spinlock_t;
183 "1: ldrex %[tmp], %[lock];"
185 #
if defined __ARM_ARCH && __ARM_ARCH >= 7
188 " strexeq %[tmp], %[c1], %[lock];"
192 : [lock]
"m" (*lock) [c1]
"r" (1)
204 " ldrex %[tmp], %[lock];"
206 #
if defined __ARM_ARCH && __ARM_ARCH >= 7
209 " strexeq %[tmp], %[c1], %[lock];"
211 : [lock]
"m" (*lock) [c1]
"r" (1)
222 " str %[c0], %[lock];"
223 #
if defined __ARM_ARCH && __ARM_ARCH >= 7
228 : [lock]
"m" (*lock) [c0]
"r" (0)
248 #if defined(__sparc__) && !defined(AST_SPINLOCK_TYPE)
249 #define AST_SPINLOCK_TYPE AST_SPINLOCK_TYPE_GAS_SPARC
250 #define AST_SPINLOCK_TYPE_LABEL "gas_sparc"
251 typedef volatile unsigned char ast_spinlock_t;
263 __asm__ __volatile__(
264 "1: ldstub %[lock], %[tmp]\n"
265 " brnz,pn %[tmp], 2f\n"
268 "2: ldub %[lock], %[tmp]\n"
269 " brnz,pt %[tmp], 2b\n"
271 " ba,a,pt %%xcc, 1b\n"
283 unsigned long result = 1;
285 __asm__ __volatile__(
286 " ldstub %[lock], %[result]\n"
287 : [result]
"=&r" (result)
292 return (result != 0);
297 __asm__ __volatile__(
321 #if defined (HAVE_PTHREAD_SPINLOCK) && !defined(AST_SPINLOCK_TYPE)
322 #define AST_SPINLOCK_TYPE AST_SPINLOCK_TYPE_PTHREAD_SPINLOCK
323 #define AST_SPINLOCK_TYPE_LABEL "pthread_spinlock"
324 typedef pthread_spinlock_t ast_spinlock_t;
328 return pthread_spin_init(lock, PTHREAD_PROCESS_PRIVATE);
333 return pthread_spin_lock(lock);
338 return pthread_spin_trylock(lock);
343 return pthread_spin_unlock(lock);
348 return pthread_spin_destroy(lock);
361 #if defined(HAVE_OSX_ATOMICS) && !defined(AST_SPINLOCK_TYPE)
362 #include <libkern/OSAtomic.h>
363 #define AST_SPINLOCK_TYPE AST_SPINLOCK_TYPE_OSX_ATOMICS
364 #define AST_SPINLOCK_TYPE_LABEL "osx_atomics"
365 typedef OSSpinLock ast_spinlock_t;
369 *lock = OS_SPINLOCK_INIT;
375 OSSpinLockLock(lock);
381 return !OSSpinLockTry(lock);
386 OSSpinLockUnlock(lock);
404 #if !defined(AST_SPINLOCK_TYPE)
405 #define AST_SPINLOCK_TYPE AST_SPINLOCK_TYPE_PTHREAD_MUTEX
406 #define AST_SPINLOCK_TYPE_LABEL "pthread_mutex"
407 typedef pthread_mutex_t ast_spinlock_t;
411 pthread_mutex_init(lock, NULL);
417 return pthread_mutex_lock(lock);
422 return pthread_mutex_trylock(lock);
427 return pthread_mutex_unlock(lock);
432 return pthread_mutex_destroy(lock);
436 #if !defined(AST_SPINLOCK_TYPE)
437 #error "No spinlock implementation could be found."
Compiler-specific macros and other items.
static force_inline int ast_spinlock_trylock(ast_spinlock_t *lock)
Try to lock a spin lock.
static force_inline int ast_spinlock_init(ast_spinlock_t *lock)
Initialize a spin lock.
ast_spinlock_type
Spinlock Implementation Types.
static force_inline int ast_spinlock_unlock(ast_spinlock_t *lock)
Unlock a spin lock.
static force_inline int ast_spinlock_lock(ast_spinlock_t *lock)
Lock a spin lock.
static force_inline int ast_spinlock_destroy(ast_spinlock_t *lock)
Destroy a spin lock.