diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2019-11-12 04:20:22 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2019-11-12 04:20:22 +0000 |
commit | a1c8a678bd969ce29c33da8b9a96a8ed5a5aad08 (patch) | |
tree | 827d852335e2cc8ec364755a3cb96e803ef5ab9a /sys/kern | |
parent | e52fa1d76ddd7041b5ae31386d0b22b38e9f2514 (diff) |
Check sleep timeout state only if the sleep has a timeout. Otherwise,
the timeout cancellation in sleep_finish_timeout() would acquire the
kernel lock every time in the no-timeout case, as noticed by mpi@.
This also reduces the contention of timeout_mutex.
OK mpi@, feedback guenther@
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_synch.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 1aa80d925e9..6b858a8c727 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_synch.c,v 1.153 2019/10/15 10:05:43 mpi Exp $ */ +/* $OpenBSD: kern_synch.c,v 1.154 2019/11/12 04:20:21 visa Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /* @@ -345,6 +345,7 @@ sleep_setup(struct sleep_state *sls, const volatile void *ident, int prio, sls->sls_catch = 0; sls->sls_do_sleep = 1; sls->sls_sig = 1; + sls->sls_timeout = 0; SCHED_LOCK(sls->sls_s); @@ -387,8 +388,13 @@ sleep_finish(struct sleep_state *sls, int do_sleep) void sleep_setup_timeout(struct sleep_state *sls, int timo) { - if (timo) - timeout_add(&curproc->p_sleep_to, timo); + struct proc *p = curproc; + + if (timo) { + KASSERT((p->p_flag & P_TIMEOUT) == 0); + sls->sls_timeout = 1; + timeout_add(&p->p_sleep_to, timo); + } } int @@ -396,13 +402,15 @@ sleep_finish_timeout(struct sleep_state *sls) { struct proc *p = curproc; - if (p->p_flag & P_TIMEOUT) { - atomic_clearbits_int(&p->p_flag, P_TIMEOUT); - return (EWOULDBLOCK); - } else { - /* This must not sleep. */ - timeout_del_barrier(&p->p_sleep_to); - KASSERT((p->p_flag & P_TIMEOUT) == 0); + if (sls->sls_timeout) { + if (p->p_flag & P_TIMEOUT) { + atomic_clearbits_int(&p->p_flag, P_TIMEOUT); + return (EWOULDBLOCK); + } else { + /* This must not sleep. */ + timeout_del_barrier(&p->p_sleep_to); + KASSERT((p->p_flag & P_TIMEOUT) == 0); + } } return (0); |