summaryrefslogtreecommitdiff
path: root/lib/librthread/arch/i386/_atomic_lock.c
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2005-12-03 18:16:20 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2005-12-03 18:16:20 +0000
commitf8598074c9df8821312f2c4a7cea9ba772625f82 (patch)
tree919fd1834c7d3b53c19dbfd42833240e246d4d45 /lib/librthread/arch/i386/_atomic_lock.c
parente9242d9ec62b39f3a6284080e22c1dc917876df5 (diff)
add userland thread library. incomplete, but functional
Diffstat (limited to 'lib/librthread/arch/i386/_atomic_lock.c')
-rw-r--r--lib/librthread/arch/i386/_atomic_lock.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/librthread/arch/i386/_atomic_lock.c b/lib/librthread/arch/i386/_atomic_lock.c
new file mode 100644
index 00000000000..7b9b46a73c7
--- /dev/null
+++ b/lib/librthread/arch/i386/_atomic_lock.c
@@ -0,0 +1,25 @@
+/* $OpenBSD: _atomic_lock.c,v 1.1 2005/12/03 18:16:19 tedu Exp $ */
+/* David Leonard, <d@csee.uq.edu.au>. Public domain. */
+
+/*
+ * Atomic lock for i386
+ */
+
+#include <machine/spinlock.h>
+
+int
+_atomic_lock(register volatile _spinlock_lock_t *lock)
+{
+ register _spinlock_lock_t old;
+
+ /*
+ * Use the eXCHanGe instruction to swap the lock value with
+ * a local variable containing the locked state.
+ */
+ old = _SPINLOCK_LOCKED;
+ __asm__("xchg %0,%1"
+ : "=r" (old), "=m" (*lock)
+ : "0" (old), "1" (*lock));
+
+ return (old != _SPINLOCK_UNLOCKED);
+}