summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormiod <miod@openbsd.org>2013-12-22 18:32:40 +0000
committermiod <miod@openbsd.org>2013-12-22 18:32:40 +0000
commit1f99c46e2161a26fffe44eee602374d0142c2644 (patch)
treec0108965f581ff302103948ab18c81e650860829
parentSet the primary CPU's PAL revision to the OSF/1 PAL revision after switching (diff)
downloadwireguard-openbsd-1f99c46e2161a26fffe44eee602374d0142c2644.tar.xz
wireguard-openbsd-1f99c46e2161a26fffe44eee602374d0142c2644.zip
MP-safe rw_cas() implementation for rwlocks.
-rw-r--r--sys/arch/alpha/include/lock.h26
1 files changed, 25 insertions, 1 deletions
diff --git a/sys/arch/alpha/include/lock.h b/sys/arch/alpha/include/lock.h
index cec638a8adb..fcaf38cb4c6 100644
--- a/sys/arch/alpha/include/lock.h
+++ b/sys/arch/alpha/include/lock.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: lock.h,v 1.4 2013/05/21 20:05:30 tedu Exp $ */
+/* $OpenBSD: lock.h,v 1.5 2013/12/22 18:32:40 miod Exp $ */
/* $NetBSD: lock.h,v 1.16 2001/12/17 23:34:57 thorpej Exp $ */
/*-
@@ -63,4 +63,28 @@ do { \
} while (0)
#endif /* MULTIPROCESSOR */
+#define rw_cas __cpu_cas
+static inline int
+__cpu_cas(volatile unsigned long *addr, unsigned long old, unsigned long new)
+{
+ unsigned long t0, v0;
+
+ __asm __volatile(
+ "1: ldq_l %1, 0(%2) \n" /* v0 = *addr */
+ " cmpeq %1, %3, %0 \n" /* t0 = v0 == old */
+ " beq %0, 2f \n"
+ " mov %4, %0 \n" /* t0 = new */
+ " stq_c %0, 0(%2) \n" /* *addr = new */
+ " beq %0, 3f \n"
+ " mb \n"
+ "2: br 4f \n"
+ "3: br 1b \n" /* update failed */
+ "4: \n"
+ : "=&r" (t0), "=&r" (v0)
+ : "r" (addr), "r" (old), "r" (new)
+ : "memory");
+
+ return (v0 != old);
+}
+
#endif /* _MACHINE_LOCK_H_ */