diff options
author | cheloha <cheloha@cvs.openbsd.org> | 2020-12-24 01:16:15 +0000 |
---|---|---|
committer | cheloha <cheloha@cvs.openbsd.org> | 2020-12-24 01:16:15 +0000 |
commit | 85548d280ccb7aabc8952779a93f84ba97e7b3fe (patch) | |
tree | 29042be1028dd82c07c86225eab2e3ebbda99e71 | |
parent | 519d2e3ecc2dce33b639b70ad3334db0f16f4f6a (diff) |
tsleep(9): add global "nowake" channel for threads avoiding wakeup(9)
It would be convenient if there were a channel a thread could sleep on
to indicate they do not want any wakeup(9) broadcasts. The easiest way
to do this is to add an "int nowake" to kern_synch.c and extern it in
sys/systm.h. You use it like this:
#include <sys/systm.h>
tsleep_nsec(&nowait, ...);
There is now no need to handroll a local dead channel, e.g.
int chan;
tsleep_nsec(&chan, ...);
which expands the stack. Local dead channels will be replaced with
&nowake in later patches.
One possible problem with this "one global channel" approach is sleep
queue congestion. If you have lots of threads sleeping on &nowake you
might slow down a wakeup(9) on a different channel that hashes into
the same queue. Unsure how much of problem this actually is, if at all.
NetBSD and FreeBSD have a "pause" interface in the kernel that chooses
a suitable channel automatically. To keep things simple and avoid
adding a new interface we will start with this global channel.
Discussed with mpi@, claudio@, kettenis@, and deraadt@.
Basically designed by kettenis@, who vetoed my other proposals.
Bugs caught by deraadt@, tb@, and patrick@.
-rw-r--r-- | sys/kern/kern_synch.c | 10 | ||||
-rw-r--r-- | sys/sys/systm.h | 4 |
2 files changed, 12 insertions, 2 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index c41f35e54ba..e266de8ef5d 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_synch.c,v 1.172 2020/12/07 16:55:29 mpi Exp $ */ +/* $OpenBSD: kern_synch.c,v 1.173 2020/12/24 01:16:14 cheloha Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /* @@ -87,6 +87,11 @@ sleep_queue_init(void) TAILQ_INIT(&slpque[i]); } +/* + * Global sleep channel for threads that do not want to + * receive wakeup(9) broadcasts. + */ +int nowake; /* * During autoconfiguration or after a panic, a sleep will simply @@ -119,6 +124,7 @@ tsleep(const volatile void *ident, int priority, const char *wmesg, int timo) #endif KASSERT((priority & ~(PRIMASK | PCATCH)) == 0); + KASSERT(ident != &nowake || ISSET(priority, PCATCH) || timo != 0); #ifdef MULTIPROCESSOR KASSERT(timo || _kernel_lock_held()); @@ -213,6 +219,7 @@ msleep(const volatile void *ident, struct mutex *mtx, int priority, #endif KASSERT((priority & ~(PRIMASK | PCATCH | PNORELOCK)) == 0); + KASSERT(ident != &nowake || ISSET(priority, PCATCH) || timo != 0); KASSERT(mtx != NULL); if (priority & PCATCH) @@ -301,6 +308,7 @@ rwsleep(const volatile void *ident, struct rwlock *rwl, int priority, int error, status; KASSERT((priority & ~(PRIMASK | PCATCH | PNORELOCK)) == 0); + KASSERT(ident != &nowake || ISSET(priority, PCATCH) || timo != 0); rw_assert_anylock(rwl); status = rw_status(rwl); diff --git a/sys/sys/systm.h b/sys/sys/systm.h index c98203833b3..49556975a7d 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -1,4 +1,4 @@ -/* $OpenBSD: systm.h,v 1.148 2020/08/26 03:29:07 visa Exp $ */ +/* $OpenBSD: systm.h,v 1.149 2020/12/24 01:16:14 cheloha Exp $ */ /* $NetBSD: systm.h,v 1.50 1996/06/09 04:55:09 briggs Exp $ */ /*- @@ -107,6 +107,8 @@ extern struct vnode *rootvp; /* vnode equivalent to above */ extern dev_t swapdev; /* swapping device */ extern struct vnode *swapdev_vp;/* vnode equivalent to above */ +extern int nowake; /* dead wakeup(9) channel */ + struct proc; struct process; #define curproc curcpu()->ci_curproc |