summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_rwlock.c
diff options
context:
space:
mode:
authorguenther <guenther@openbsd.org>2014-09-01 03:37:10 +0000
committerguenther <guenther@openbsd.org>2014-09-01 03:37:10 +0000
commitc73429fe513b33d5a02a4f6a53dc10a9549349ec (patch)
treeff042e9b2b3bcf3dfabc82f8fa4cf4df54631245 /sys/kern/kern_rwlock.c
parentSimplify the syslog.conf example: .info means that *and higher* (diff)
downloadwireguard-openbsd-c73429fe513b33d5a02a4f6a53dc10a9549349ec.tar.xz
wireguard-openbsd-c73429fe513b33d5a02a4f6a53dc10a9549349ec.zip
Add explicit membars, so that we can stop requiring rw_cas() to
provide the magic. ok matthew@ dlg@
Diffstat (limited to 'sys/kern/kern_rwlock.c')
-rw-r--r--sys/kern/kern_rwlock.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
index e1def9e874d..bf90a4428be 100644
--- a/sys/kern/kern_rwlock.c
+++ b/sys/kern/kern_rwlock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_rwlock.c,v 1.22 2014/07/09 13:32:00 guenther Exp $ */
+/* $OpenBSD: kern_rwlock.c,v 1.23 2014/09/01 03:37:10 guenther Exp $ */
/*
* Copyright (c) 2002, 2003 Artur Grabowski <art@openbsd.org>
@@ -22,6 +22,7 @@
#include <sys/proc.h>
#include <sys/rwlock.h>
#include <sys/limits.h>
+#include <sys/atomic.h>
#include <machine/lock.h>
@@ -85,6 +86,8 @@ rw_enter_read(struct rwlock *rwl)
if (__predict_false((owner & RWLOCK_WRLOCK) ||
rw_cas(&rwl->rwl_owner, owner, owner + RWLOCK_READ_INCR)))
rw_enter(rwl, RW_READ);
+ else
+ membar_enter();
}
void
@@ -95,6 +98,8 @@ rw_enter_write(struct rwlock *rwl)
if (__predict_false(rw_cas(&rwl->rwl_owner, 0,
RW_PROC(p) | RWLOCK_WRLOCK)))
rw_enter(rwl, RW_WRITE);
+ else
+ membar_enter();
}
void
@@ -104,6 +109,7 @@ rw_exit_read(struct rwlock *rwl)
rw_assert_rdlock(rwl);
+ membar_exit();
if (__predict_false((owner & RWLOCK_WAIT) ||
rw_cas(&rwl->rwl_owner, owner, owner - RWLOCK_READ_INCR)))
rw_exit(rwl);
@@ -116,6 +122,7 @@ rw_exit_write(struct rwlock *rwl)
rw_assert_wrlock(rwl);
+ membar_exit();
if (__predict_false((owner & RWLOCK_WAIT) ||
rw_cas(&rwl->rwl_owner, owner, 0)))
rw_exit(rwl);
@@ -215,6 +222,7 @@ retry:
if (__predict_false(rw_cas(&rwl->rwl_owner, o, o + inc)))
goto retry;
+ membar_enter();
/*
* If old lock had RWLOCK_WAIT and RWLOCK_WRLOCK set, it means we
@@ -240,6 +248,7 @@ rw_exit(struct rwlock *rwl)
else
rw_assert_rdlock(rwl);
+ membar_exit();
do {
owner = rwl->rwl_owner;
if (wrlock)