Set LW_SINTR earlier so it doesn't pose a problem for doing interruptable
waits with turnstiles (not currently done).
This commit is contained in:
parent
a29147fa13
commit
46a9878a41
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_condvar.c,v 1.46 2020/04/13 15:54:45 maxv Exp $ */
|
||||
/* $NetBSD: kern_condvar.c,v 1.47 2020/04/19 20:35:29 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006, 2007, 2008, 2019, 2020 The NetBSD Foundation, Inc.
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_condvar.c,v 1.46 2020/04/13 15:54:45 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_condvar.c,v 1.47 2020/04/19 20:35:29 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -116,7 +116,7 @@ cv_destroy(kcondvar_t *cv)
|
|||
* condition variable, and increment the number of waiters.
|
||||
*/
|
||||
static inline void
|
||||
cv_enter(kcondvar_t *cv, kmutex_t *mtx, lwp_t *l)
|
||||
cv_enter(kcondvar_t *cv, kmutex_t *mtx, lwp_t *l, bool catch_p)
|
||||
{
|
||||
sleepq_t *sq;
|
||||
kmutex_t *mp;
|
||||
|
@ -129,7 +129,7 @@ cv_enter(kcondvar_t *cv, kmutex_t *mtx, lwp_t *l)
|
|||
mp = sleepq_hashlock(cv);
|
||||
sq = CV_SLEEPQ(cv);
|
||||
sleepq_enter(sq, l, mp);
|
||||
sleepq_enqueue(sq, cv, CV_WMESG(cv), &cv_syncobj);
|
||||
sleepq_enqueue(sq, cv, CV_WMESG(cv), &cv_syncobj, catch_p);
|
||||
mutex_exit(mtx);
|
||||
KASSERT(cv_has_waiters(cv));
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ cv_wait(kcondvar_t *cv, kmutex_t *mtx)
|
|||
|
||||
KASSERT(mutex_owned(mtx));
|
||||
|
||||
cv_enter(cv, mtx, l);
|
||||
cv_enter(cv, mtx, l, false);
|
||||
(void)sleepq_block(0, false);
|
||||
mutex_enter(mtx);
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ cv_wait_sig(kcondvar_t *cv, kmutex_t *mtx)
|
|||
|
||||
KASSERT(mutex_owned(mtx));
|
||||
|
||||
cv_enter(cv, mtx, l);
|
||||
cv_enter(cv, mtx, l, true);
|
||||
error = sleepq_block(0, true);
|
||||
mutex_enter(mtx);
|
||||
return error;
|
||||
|
@ -213,7 +213,7 @@ cv_timedwait(kcondvar_t *cv, kmutex_t *mtx, int timo)
|
|||
|
||||
KASSERT(mutex_owned(mtx));
|
||||
|
||||
cv_enter(cv, mtx, l);
|
||||
cv_enter(cv, mtx, l, false);
|
||||
error = sleepq_block(timo, false);
|
||||
mutex_enter(mtx);
|
||||
return error;
|
||||
|
@ -238,7 +238,7 @@ cv_timedwait_sig(kcondvar_t *cv, kmutex_t *mtx, int timo)
|
|||
|
||||
KASSERT(mutex_owned(mtx));
|
||||
|
||||
cv_enter(cv, mtx, l);
|
||||
cv_enter(cv, mtx, l, true);
|
||||
error = sleepq_block(timo, true);
|
||||
mutex_enter(mtx);
|
||||
return error;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_sleepq.c,v 1.65 2020/04/13 15:54:45 maxv Exp $ */
|
||||
/* $NetBSD: kern_sleepq.c,v 1.66 2020/04/19 20:35:29 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006, 2007, 2008, 2009, 2019, 2020 The NetBSD Foundation, Inc.
|
||||
|
@ -35,7 +35,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.65 2020/04/13 15:54:45 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.66 2020/04/19 20:35:29 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -210,13 +210,15 @@ sleepq_insert(sleepq_t *sq, lwp_t *l, syncobj_t *sobj)
|
|||
* lock) must have be released (see sleeptab_lookup(), sleepq_enter()).
|
||||
*/
|
||||
void
|
||||
sleepq_enqueue(sleepq_t *sq, wchan_t wchan, const char *wmesg, syncobj_t *sobj)
|
||||
sleepq_enqueue(sleepq_t *sq, wchan_t wchan, const char *wmesg, syncobj_t *sobj,
|
||||
bool catch_p)
|
||||
{
|
||||
lwp_t *l = curlwp;
|
||||
|
||||
KASSERT(lwp_locked(l, NULL));
|
||||
KASSERT(l->l_stat == LSONPROC);
|
||||
KASSERT(l->l_wchan == NULL && l->l_sleepq == NULL);
|
||||
KASSERT((l->l_flag & LW_SINTR) == 0);
|
||||
|
||||
l->l_syncobj = sobj;
|
||||
l->l_wchan = wchan;
|
||||
|
@ -224,6 +226,8 @@ sleepq_enqueue(sleepq_t *sq, wchan_t wchan, const char *wmesg, syncobj_t *sobj)
|
|||
l->l_wmesg = wmesg;
|
||||
l->l_slptime = 0;
|
||||
l->l_stat = LSSLEEP;
|
||||
if (catch_p)
|
||||
l->l_flag |= LW_SINTR;
|
||||
|
||||
sleepq_insert(sq, l, sobj);
|
||||
|
||||
|
@ -254,13 +258,9 @@ sleepq_block(int timo, bool catch_p)
|
|||
|
||||
/*
|
||||
* If sleeping interruptably, check for pending signals, exits or
|
||||
* core dump events. XXX The set of LW_SINTR here assumes no unlock
|
||||
* between sleepq_enqueue() and sleepq_block(). Unlock between
|
||||
* those only happens with turnstiles, which never set catch_p.
|
||||
* Ugly but safe.
|
||||
* core dump events.
|
||||
*/
|
||||
if (catch_p) {
|
||||
l->l_flag |= LW_SINTR;
|
||||
if ((l->l_flag & (LW_CANCELLED|LW_WEXIT|LW_WCORE)) != 0) {
|
||||
l->l_flag &= ~LW_CANCELLED;
|
||||
error = EINTR;
|
||||
|
@ -273,6 +273,13 @@ sleepq_block(int timo, bool catch_p)
|
|||
/* lwp_unsleep() will release the lock */
|
||||
lwp_unsleep(l, true);
|
||||
} else {
|
||||
/*
|
||||
* The LWP may have already been awoken if the caller
|
||||
* dropped the sleep queue lock between sleepq_enqueue() and
|
||||
* sleepq_block(). If that happends l_stat will be LSONPROC
|
||||
* and mi_switch() will treat this as a preemption. No need
|
||||
* to do anything special here.
|
||||
*/
|
||||
if (timo) {
|
||||
l->l_flag &= ~LW_STIMO;
|
||||
callout_schedule(&l->l_timeout_ch, timo);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_synch.c,v 1.346 2020/04/04 20:21:53 ad Exp $ */
|
||||
/* $NetBSD: kern_synch.c,v 1.347 2020/04/19 20:35:29 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2004, 2006, 2007, 2008, 2009, 2019, 2020
|
||||
|
@ -69,7 +69,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.346 2020/04/04 20:21:53 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.347 2020/04/19 20:35:29 ad Exp $");
|
||||
|
||||
#include "opt_kstack.h"
|
||||
#include "opt_dtrace.h"
|
||||
|
@ -173,6 +173,7 @@ tsleep(wchan_t ident, pri_t priority, const char *wmesg, int timo)
|
|||
struct lwp *l = curlwp;
|
||||
sleepq_t *sq;
|
||||
kmutex_t *mp;
|
||||
bool catch_p;
|
||||
|
||||
KASSERT((l->l_pflag & LP_INTR) == 0);
|
||||
KASSERT(ident != &lbolt);
|
||||
|
@ -183,10 +184,11 @@ tsleep(wchan_t ident, pri_t priority, const char *wmesg, int timo)
|
|||
}
|
||||
|
||||
l->l_kpriority = true;
|
||||
catch_p = priority & PCATCH;
|
||||
sq = sleeptab_lookup(&sleeptab, ident, &mp);
|
||||
sleepq_enter(sq, l, mp);
|
||||
sleepq_enqueue(sq, ident, wmesg, &sleep_syncobj);
|
||||
return sleepq_block(timo, priority & PCATCH);
|
||||
sleepq_enqueue(sq, ident, wmesg, &sleep_syncobj, catch_p);
|
||||
return sleepq_block(timo, catch_p);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -196,6 +198,7 @@ mtsleep(wchan_t ident, pri_t priority, const char *wmesg, int timo,
|
|||
struct lwp *l = curlwp;
|
||||
sleepq_t *sq;
|
||||
kmutex_t *mp;
|
||||
bool catch_p;
|
||||
int error;
|
||||
|
||||
KASSERT((l->l_pflag & LP_INTR) == 0);
|
||||
|
@ -207,11 +210,12 @@ mtsleep(wchan_t ident, pri_t priority, const char *wmesg, int timo,
|
|||
}
|
||||
|
||||
l->l_kpriority = true;
|
||||
catch_p = priority & PCATCH;
|
||||
sq = sleeptab_lookup(&sleeptab, ident, &mp);
|
||||
sleepq_enter(sq, l, mp);
|
||||
sleepq_enqueue(sq, ident, wmesg, &sleep_syncobj);
|
||||
sleepq_enqueue(sq, ident, wmesg, &sleep_syncobj, catch_p);
|
||||
mutex_exit(mtx);
|
||||
error = sleepq_block(timo, priority & PCATCH);
|
||||
error = sleepq_block(timo, catch_p);
|
||||
|
||||
if ((priority & PNORELOCK) == 0)
|
||||
mutex_enter(mtx);
|
||||
|
@ -238,7 +242,7 @@ kpause(const char *wmesg, bool intr, int timo, kmutex_t *mtx)
|
|||
l->l_kpriority = true;
|
||||
lwp_lock(l);
|
||||
KERNEL_UNLOCK_ALL(NULL, &l->l_biglocks);
|
||||
sleepq_enqueue(NULL, l, wmesg, &kpause_syncobj);
|
||||
sleepq_enqueue(NULL, l, wmesg, &kpause_syncobj, intr);
|
||||
error = sleepq_block(timo, intr);
|
||||
if (mtx != NULL)
|
||||
mutex_enter(mtx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_timeout.c,v 1.60 2020/04/13 15:54:45 maxv Exp $ */
|
||||
/* $NetBSD: kern_timeout.c,v 1.61 2020/04/19 20:35:29 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003, 2006, 2007, 2008, 2009, 2019 The NetBSD Foundation, Inc.
|
||||
|
@ -59,7 +59,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_timeout.c,v 1.60 2020/04/13 15:54:45 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_timeout.c,v 1.61 2020/04/19 20:35:29 ad Exp $");
|
||||
|
||||
/*
|
||||
* Timeouts are kept in a hierarchical timing wheel. The c_time is the
|
||||
|
@ -539,7 +539,7 @@ callout_wait(callout_impl_t *c, void *interlock, kmutex_t *lock)
|
|||
l->l_kpriority = true;
|
||||
sleepq_enter(&cc->cc_sleepq, l, cc->cc_lock);
|
||||
sleepq_enqueue(&cc->cc_sleepq, cc, "callout",
|
||||
&sleep_syncobj);
|
||||
&sleep_syncobj, false);
|
||||
sleepq_block(0, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_turnstile.c,v 1.38 2020/03/26 22:43:19 ad Exp $ */
|
||||
/* $NetBSD: kern_turnstile.c,v 1.39 2020/04/19 20:35:29 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002, 2006, 2007, 2009, 2019, 2020
|
||||
|
@ -61,7 +61,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.38 2020/03/26 22:43:19 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.39 2020/04/19 20:35:29 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/lockdebug.h>
|
||||
|
@ -429,7 +429,7 @@ turnstile_block(turnstile_t *ts, int q, wchan_t obj, syncobj_t *sobj)
|
|||
obase = l->l_kpribase;
|
||||
if (obase < PRI_KTHREAD)
|
||||
l->l_kpribase = PRI_KTHREAD;
|
||||
sleepq_enqueue(sq, obj, "tstile", sobj);
|
||||
sleepq_enqueue(sq, obj, "tstile", sobj, false);
|
||||
|
||||
/*
|
||||
* Disable preemption across this entire block, as we may drop
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sys_lwp.c,v 1.76 2020/04/04 20:20:12 thorpej Exp $ */
|
||||
/* $NetBSD: sys_lwp.c,v 1.77 2020/04/19 20:35:29 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001, 2006, 2007, 2008, 2019, 2020 The NetBSD Foundation, Inc.
|
||||
|
@ -35,7 +35,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.76 2020/04/04 20:20:12 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.77 2020/04/19 20:35:29 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -542,7 +542,7 @@ lwp_park(clockid_t clock_id, int flags, struct timespec *ts)
|
|||
return EALREADY;
|
||||
}
|
||||
l->l_biglocks = 0;
|
||||
sleepq_enqueue(NULL, l, "parked", &lwp_park_syncobj);
|
||||
sleepq_enqueue(NULL, l, "parked", &lwp_park_syncobj, true);
|
||||
error = sleepq_block(timo, true);
|
||||
switch (error) {
|
||||
case EWOULDBLOCK:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sys_select.c,v 1.53 2020/03/26 19:46:42 ad Exp $ */
|
||||
/* $NetBSD: sys_select.c,v 1.54 2020/04/19 20:35:29 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007, 2008, 2009, 2010, 2019, 2020 The NetBSD Foundation, Inc.
|
||||
|
@ -84,7 +84,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_select.c,v 1.53 2020/03/26 19:46:42 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_select.c,v 1.54 2020/04/19 20:35:29 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -321,7 +321,7 @@ state_check:
|
|||
l->l_selflag = SEL_BLOCKING;
|
||||
l->l_kpriority = true;
|
||||
sleepq_enter(&sc->sc_sleepq, l, lock);
|
||||
sleepq_enqueue(&sc->sc_sleepq, sc, opname, &select_sobj);
|
||||
sleepq_enqueue(&sc->sc_sleepq, sc, opname, &select_sobj, true);
|
||||
error = sleepq_block(timo, true);
|
||||
if (error != 0) {
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sleepq.h,v 1.28 2020/03/26 19:46:42 ad Exp $ */
|
||||
/* $NetBSD: sleepq.h,v 1.29 2020/04/19 20:35:29 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002, 2006, 2007, 2008, 2009, 2019, 2020
|
||||
|
@ -60,7 +60,8 @@ typedef struct sleeptab {
|
|||
|
||||
void sleepq_init(sleepq_t *);
|
||||
void sleepq_remove(sleepq_t *, lwp_t *);
|
||||
void sleepq_enqueue(sleepq_t *, wchan_t, const char *, struct syncobj *);
|
||||
void sleepq_enqueue(sleepq_t *, wchan_t, const char *, struct syncobj *,
|
||||
bool);
|
||||
void sleepq_unsleep(lwp_t *, bool);
|
||||
void sleepq_timeout(void *);
|
||||
void sleepq_wake(sleepq_t *, wchan_t, u_int, kmutex_t *);
|
||||
|
|
Loading…
Reference in New Issue