diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-09-13 08:32:45 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-09-13 08:32:45 +0000 |
commit | 3cf01033387a1a629cdfdbc5978ea10169f2f116 (patch) | |
tree | d4721a733bb958d748aa3feb3d741996e2f09bee /sys/kern/kern_synch.c | |
parent | a34611092ff653bcbfd32fec7581c3afdab2d7d0 (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.c | 36 |
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) |