summaryrefslogtreecommitdiff
path: root/sys/kern/kern_synch.c
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2016-09-13 08:32:45 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2016-09-13 08:32:45 +0000
commit3cf01033387a1a629cdfdbc5978ea10169f2f116 (patch)
treed4721a733bb958d748aa3feb3d741996e2f09bee /sys/kern/kern_synch.c
parenta34611092ff653bcbfd32fec7581c3afdab2d7d0 (diff)
Introduce rwsleep(9), an equivalent to msleep(9) but for code protected
by a write lock. ok guenther@, vgross@
Diffstat (limited to 'sys/kern/kern_synch.c')
-rw-r--r--sys/kern/kern_synch.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 4e87d06b64b..beeefe06458 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_synch.c,v 1.134 2016/09/03 15:06:06 akfaew Exp $ */
+/* $OpenBSD: kern_synch.c,v 1.135 2016/09/13 08:32:44 mpi Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*
@@ -226,6 +226,40 @@ msleep(const volatile void *ident, struct mutex *mtx, int priority,
return (error);
}
+/*
+ * Same as tsleep, but if we have a rwlock provided, then once we've
+ * entered the sleep queue we drop the it. After sleeping we re-lock.
+ */
+int
+rwsleep(const volatile void *ident, struct rwlock *wl, int priority,
+ const char *wmesg, int timo)
+{
+ struct sleep_state sls;
+ int error, error1;
+
+ KASSERT((priority & ~(PRIMASK | PCATCH | PNORELOCK)) == 0);
+ rw_assert_wrlock(wl);
+
+ sleep_setup(&sls, ident, priority, wmesg);
+ sleep_setup_timeout(&sls, timo);
+ sleep_setup_signal(&sls, priority);
+
+ rw_exit_write(wl);
+
+ sleep_finish(&sls, 1);
+ error1 = sleep_finish_timeout(&sls);
+ error = sleep_finish_signal(&sls);
+
+ if ((priority & PNORELOCK) == 0)
+ rw_enter_write(wl);
+
+ /* Signal errors are higher priority than timeouts. */
+ if (error == 0 && error1 != 0)
+ error = error1;
+
+ return (error);
+}
+
void
sleep_setup(struct sleep_state *sls, const volatile void *ident, int prio,
const char *wmesg)