summaryrefslogtreecommitdiff
path: root/lib/librthread/arch/i386/_atomic_lock.c
diff options
context:
space:
mode:
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);
+}