summaryrefslogtreecommitdiff
path: root/lib/libpthread/sys/slow_atomic_lock.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libpthread/sys/slow_atomic_lock.c')
-rw-r--r--lib/libpthread/sys/slow_atomic_lock.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/libpthread/sys/slow_atomic_lock.c b/lib/libpthread/sys/slow_atomic_lock.c
new file mode 100644
index 00000000000..96be0897dc9
--- /dev/null
+++ b/lib/libpthread/sys/slow_atomic_lock.c
@@ -0,0 +1,33 @@
+/* $OpenBSD: slow_atomic_lock.c,v 1.1 1998/11/20 11:15:38 d Exp $ */
+
+#include "pthread_private.h"
+#include "spinlock.h"
+#include <signal.h>
+
+/*
+ * uthread atomic lock:
+ * attempt to acquire a lock (by giving it a non-zero value).
+ * Return zero on success, or the lock's value on failure
+ * This uses signal masking to make sure that no other thread
+ * can modify the lock while processing, hence it is very slow.
+ */
+register_t
+_thread_slow_atomic_lock(volatile register_t *lock)
+{
+ register_t old;
+ sigset_t oldset, newset = (sigset_t)~0;
+
+ /* block signals - incurs a context switch */
+ if (_thread_sys_sigprocmask(SIG_SETMASK, &newset, &oldset) < 0)
+ PANIC("_atomic_lock block");
+
+ old = *lock;
+ if (old == 0)
+ *lock = 1;
+
+ /* restore signal mask to what it was */
+ if (_thread_sys_sigprocmask(SIG_SETMASK, &oldset, NULL) < 0)
+ PANIC("_atomic_lock restore");
+
+ return old;
+}