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