1 /* $OpenBSD: slow_atomic_lock.c,v 1.3 1998/12/21 07:38:43 d Exp $ */ 2 3 #include <pthread.h> 4 #include "pthread_private.h" 5 #include "spinlock.h" 6 #include <signal.h> 7 8 /* 9 * uthread atomic lock: 10 * attempt to acquire a lock (by giving it a non-zero value). 11 * Return zero on success, or the lock's value on failure 12 * This uses signal masking to make sure that no other thread 13 * can modify the lock while processing, hence it is very slow. 14 */ 15 int _thread_slow_atomic_lock(volatile _spinlock_lock_t * lock)16_thread_slow_atomic_lock(volatile _spinlock_lock_t *lock) 17 { 18 _spinlock_lock_t old; 19 sigset_t oldset, newset = (sigset_t)~0; 20 21 /* block signals - incurs a context switch */ 22 if (_thread_sys_sigprocmask(SIG_SETMASK, &newset, &oldset) < 0) 23 PANIC("_atomic_lock block"); 24 25 old = *lock; 26 if (old == _SPINLOCK_UNLOCKED) 27 *lock = _SPINLOCK_LOCKED; 28 29 /* restore signal mask to what it was */ 30 if (_thread_sys_sigprocmask(SIG_SETMASK, &oldset, NULL) < 0) 31 PANIC("_atomic_lock restore"); 32 33 return (old != _SPINLOCK_UNLOCKED); 34 } 35 36 int _thread_slow_atomic_is_locked(volatile _spinlock_lock_t * lock)37_thread_slow_atomic_is_locked(volatile _spinlock_lock_t *lock) 38 { 39 40 return (*lock != _SPINLOCK_UNLOCKED); 41 } 42