Module Name: src Committed By: ad Date: Thu Mar 26 19:46:42 UTC 2020
Modified Files: src/sys/kern: kern_condvar.c kern_sleepq.c kern_turnstile.c sys_select.c src/sys/sys: condvar.h lwp.h sleepq.h Log Message: Change sleepq_t from a TAILQ to a LIST and remove SOBJ_SLEEPQ_FIFO. Only select/poll used the FIFO method and that was for collisions which rarely occur. Shrinks sleep_t and condvar_t. To generate a diff of this commit: cvs rdiff -u -r1.43 -r1.44 src/sys/kern/kern_condvar.c cvs rdiff -u -r1.62 -r1.63 src/sys/kern/kern_sleepq.c cvs rdiff -u -r1.36 -r1.37 src/sys/kern/kern_turnstile.c cvs rdiff -u -r1.52 -r1.53 src/sys/kern/sys_select.c cvs rdiff -u -r1.14 -r1.15 src/sys/sys/condvar.h cvs rdiff -u -r1.202 -r1.203 src/sys/sys/lwp.h cvs rdiff -u -r1.27 -r1.28 src/sys/sys/sleepq.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_condvar.c diff -u src/sys/kern/kern_condvar.c:1.43 src/sys/kern/kern_condvar.c:1.44 --- src/sys/kern/kern_condvar.c:1.43 Sat Feb 15 17:09:24 2020 +++ src/sys/kern/kern_condvar.c Thu Mar 26 19:46:42 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_condvar.c,v 1.43 2020/02/15 17:09:24 ad Exp $ */ +/* $NetBSD: kern_condvar.c,v 1.44 2020/03/26 19:46:42 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.43 2020/02/15 17:09:24 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_condvar.c,v 1.44 2020/03/26 19:46:42 ad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -48,20 +48,19 @@ __KERNEL_RCSID(0, "$NetBSD: kern_condvar /* * Accessors for the private contents of the kcondvar_t data type. * - * cv_opaque[0] sleepq... - * cv_opaque[1] ...pointers - * cv_opaque[2] description for ps(1) + * cv_opaque[0] sleepq_t + * cv_opaque[1] description for ps(1) * - * cv_opaque[0..1] is protected by the interlock passed to cv_wait() (enqueue + * cv_opaque[0] is protected by the interlock passed to cv_wait() (enqueue * only), and the sleep queue lock acquired with sleepq_hashlock() (enqueue * and dequeue). * - * cv_opaque[2] (the wmesg) is static and does not change throughout the life + * cv_opaque[1] (the wmesg) is static and does not change throughout the life * of the CV. */ #define CV_SLEEPQ(cv) ((sleepq_t *)(cv)->cv_opaque) -#define CV_WMESG(cv) ((const char *)(cv)->cv_opaque[2]) -#define CV_SET_WMESG(cv, v) (cv)->cv_opaque[2] = __UNCONST(v) +#define CV_WMESG(cv) ((const char *)(cv)->cv_opaque[1]) +#define CV_SET_WMESG(cv, v) (cv)->cv_opaque[1] = __UNCONST(v) #define CV_DEBUG_P(cv) (CV_WMESG(cv) != nodebug) #define CV_RA ((uintptr_t)__builtin_return_address(0)) @@ -486,7 +485,7 @@ cv_signal(kcondvar_t *cv) /* LOCKDEBUG_WAKEUP(CV_DEBUG_P(cv), cv, CV_RA); */ KASSERT(cv_is_valid(cv)); - if (__predict_false(!TAILQ_EMPTY(CV_SLEEPQ(cv)))) + if (__predict_false(!LIST_EMPTY(CV_SLEEPQ(cv)))) cv_wakeup_one(cv); } @@ -508,7 +507,7 @@ cv_wakeup_one(kcondvar_t *cv) mp = sleepq_hashlock(cv); sq = CV_SLEEPQ(cv); - l = TAILQ_FIRST(sq); + l = LIST_FIRST(sq); if (__predict_false(l == NULL)) { mutex_spin_exit(mp); return; @@ -536,7 +535,7 @@ cv_broadcast(kcondvar_t *cv) /* LOCKDEBUG_WAKEUP(CV_DEBUG_P(cv), cv, CV_RA); */ KASSERT(cv_is_valid(cv)); - if (__predict_false(!TAILQ_EMPTY(CV_SLEEPQ(cv)))) + if (__predict_false(!LIST_EMPTY(CV_SLEEPQ(cv)))) cv_wakeup_all(cv); } @@ -558,11 +557,11 @@ cv_wakeup_all(kcondvar_t *cv) mp = sleepq_hashlock(cv); sq = CV_SLEEPQ(cv); - for (l = TAILQ_FIRST(sq); l != NULL; l = next) { + for (l = LIST_FIRST(sq); l != NULL; l = next) { KASSERT(l->l_sleepq == sq); KASSERT(l->l_mutex == mp); KASSERT(l->l_wchan == cv); - next = TAILQ_NEXT(l, l_sleepchain); + next = LIST_NEXT(l, l_sleepchain); CV_LOCKDEBUG_PROCESS(l, cv); sleepq_remove(sq, l); } @@ -581,7 +580,7 @@ bool cv_has_waiters(kcondvar_t *cv) { - return !TAILQ_EMPTY(CV_SLEEPQ(cv)); + return !LIST_EMPTY(CV_SLEEPQ(cv)); } /* Index: src/sys/kern/kern_sleepq.c diff -u src/sys/kern/kern_sleepq.c:1.62 src/sys/kern/kern_sleepq.c:1.63 --- src/sys/kern/kern_sleepq.c:1.62 Tue Mar 24 21:05:06 2020 +++ src/sys/kern/kern_sleepq.c Thu Mar 26 19:46:42 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_sleepq.c,v 1.62 2020/03/24 21:05:06 ad Exp $ */ +/* $NetBSD: kern_sleepq.c,v 1.63 2020/03/26 19:46:42 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.62 2020/03/24 21:05:06 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.63 2020/03/26 19:46:42 ad Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -98,7 +98,7 @@ void sleepq_init(sleepq_t *sq) { - TAILQ_INIT(sq); + LIST_INIT(sq); } /* @@ -116,7 +116,7 @@ sleepq_remove(sleepq_t *sq, lwp_t *l) if ((l->l_syncobj->sobj_flag & SOBJ_SLEEPQ_NULL) == 0) { KASSERT(sq != NULL); - TAILQ_REMOVE(sq, l, l_sleepchain); + LIST_REMOVE(l, l_sleepchain); } else { KASSERT(sq == NULL); } @@ -191,18 +191,15 @@ sleepq_insert(sleepq_t *sq, lwp_t *l, sy lwp_t *l2; const pri_t pri = lwp_eprio(l); - TAILQ_FOREACH(l2, sq, l_sleepchain) { + LIST_FOREACH(l2, sq, l_sleepchain) { if (lwp_eprio(l2) < pri) { - TAILQ_INSERT_BEFORE(l2, l, l_sleepchain); + LIST_INSERT_BEFORE(l2, l, l_sleepchain); return; } } } - if ((sobj->sobj_flag & SOBJ_SLEEPQ_LIFO) != 0) - TAILQ_INSERT_HEAD(sq, l, l_sleepchain); - else - TAILQ_INSERT_TAIL(sq, l, l_sleepchain); + LIST_INSERT_HEAD(sq, l, l_sleepchain); } /* @@ -334,10 +331,10 @@ sleepq_wake(sleepq_t *sq, wchan_t wchan, KASSERT(mutex_owned(mp)); - for (l = TAILQ_FIRST(sq); l != NULL; l = next) { + for (l = LIST_FIRST(sq); l != NULL; l = next) { KASSERT(l->l_sleepq == sq); KASSERT(l->l_mutex == mp); - next = TAILQ_NEXT(l, l_sleepchain); + next = LIST_NEXT(l, l_sleepchain); if (l->l_wchan != wchan) continue; sleepq_remove(sq, l); @@ -463,10 +460,10 @@ sleepq_reinsert(sleepq_t *sq, lwp_t *l) * sleep queue lock held and need to see a non-empty queue * head if there are waiters. */ - if (TAILQ_FIRST(sq) == l && TAILQ_NEXT(l, l_sleepchain) == NULL) { + if (LIST_FIRST(sq) == l && LIST_NEXT(l, l_sleepchain) == NULL) { return; } - TAILQ_REMOVE(sq, l, l_sleepchain); + LIST_REMOVE(l, l_sleepchain); sleepq_insert(sq, l, l->l_syncobj); } Index: src/sys/kern/kern_turnstile.c diff -u src/sys/kern/kern_turnstile.c:1.36 src/sys/kern/kern_turnstile.c:1.37 --- src/sys/kern/kern_turnstile.c:1.36 Tue Jan 21 20:31:57 2020 +++ src/sys/kern/kern_turnstile.c Thu Mar 26 19:46:42 2020 @@ -1,7 +1,8 @@ -/* $NetBSD: kern_turnstile.c,v 1.36 2020/01/21 20:31:57 ad Exp $ */ +/* $NetBSD: kern_turnstile.c,v 1.37 2020/03/26 19:46:42 ad Exp $ */ /*- - * Copyright (c) 2002, 2006, 2007, 2009, 2019 The NetBSD Foundation, Inc. + * Copyright (c) 2002, 2006, 2007, 2009, 2019, 2020 + * The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -60,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.36 2020/01/21 20:31:57 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.37 2020/03/26 19:46:42 ad Exp $"); #include <sys/param.h> #include <sys/lockdebug.h> @@ -397,8 +398,8 @@ turnstile_block(turnstile_t *ts, int q, */ ts = l->l_ts; KASSERT(TS_ALL_WAITERS(ts) == 0); - KASSERT(TAILQ_EMPTY(&ts->ts_sleepq[TS_READER_Q]) && - TAILQ_EMPTY(&ts->ts_sleepq[TS_WRITER_Q])); + KASSERT(LIST_EMPTY(&ts->ts_sleepq[TS_READER_Q]) && + LIST_EMPTY(&ts->ts_sleepq[TS_WRITER_Q])); ts->ts_obj = obj; ts->ts_inheritor = NULL; LIST_INSERT_HEAD(tc, ts, ts_chain); @@ -416,8 +417,8 @@ turnstile_block(turnstile_t *ts, int q, KASSERT(ts->ts_obj == obj); KASSERT(TS_ALL_WAITERS(ts) != 0); - KASSERT(!TAILQ_EMPTY(&ts->ts_sleepq[TS_READER_Q]) || - !TAILQ_EMPTY(&ts->ts_sleepq[TS_WRITER_Q])); + KASSERT(!LIST_EMPTY(&ts->ts_sleepq[TS_READER_Q]) || + !LIST_EMPTY(&ts->ts_sleepq[TS_WRITER_Q])); } sq = &ts->ts_sleepq[q]; @@ -476,7 +477,7 @@ turnstile_wakeup(turnstile_t *ts, int q, if (nl != NULL) { #if defined(DEBUG) || defined(LOCKDEBUG) - TAILQ_FOREACH(l, sq, l_sleepchain) { + LIST_FOREACH(l, sq, l_sleepchain) { if (l == nl) break; } @@ -486,7 +487,7 @@ turnstile_wakeup(turnstile_t *ts, int q, turnstile_remove(ts, nl, q); } else { while (count-- > 0) { - l = TAILQ_FIRST(sq); + l = LIST_FIRST(sq); KASSERT(l != NULL); turnstile_remove(ts, l, q); } Index: src/sys/kern/sys_select.c diff -u src/sys/kern/sys_select.c:1.52 src/sys/kern/sys_select.c:1.53 --- src/sys/kern/sys_select.c:1.52 Sat Feb 15 17:09:24 2020 +++ src/sys/kern/sys_select.c Thu Mar 26 19:46:42 2020 @@ -1,7 +1,7 @@ -/* $NetBSD: sys_select.c,v 1.52 2020/02/15 17:09:24 ad Exp $ */ +/* $NetBSD: sys_select.c,v 1.53 2020/03/26 19:46:42 ad Exp $ */ /*- - * Copyright (c) 2007, 2008, 2009, 2010, 2019 The NetBSD Foundation, Inc. + * Copyright (c) 2007, 2008, 2009, 2010, 2019, 2020 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -84,7 +84,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sys_select.c,v 1.52 2020/02/15 17:09:24 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_select.c,v 1.53 2020/03/26 19:46:42 ad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -136,8 +136,14 @@ static const int sel_flag[] = { POLLRDBAND }; +/* + * LWPs are woken using the sleep queue only due to a collision, the case + * with the maximum Suck Factor. Save the cost of sorting for named waiters + * by inserting in LIFO order. In the future it would be preferable to not + * enqueue LWPs at all, unless subject to a collision. + */ syncobj_t select_sobj = { - .sobj_flag = SOBJ_SLEEPQ_FIFO, + .sobj_flag = SOBJ_SLEEPQ_LIFO, .sobj_unsleep = sleepq_unsleep, .sobj_changepri = sleepq_changepri, .sobj_lendpri = sleepq_lendpri, Index: src/sys/sys/condvar.h diff -u src/sys/sys/condvar.h:1.14 src/sys/sys/condvar.h:1.15 --- src/sys/sys/condvar.h:1.14 Mon Jul 3 03:12:42 2017 +++ src/sys/sys/condvar.h Thu Mar 26 19:46:42 2020 @@ -1,7 +1,7 @@ -/* $NetBSD: condvar.h,v 1.14 2017/07/03 03:12:42 riastradh Exp $ */ +/* $NetBSD: condvar.h,v 1.15 2020/03/26 19:46:42 ad Exp $ */ /*- - * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. + * Copyright (c) 2006, 2007, 2008, 2020 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -33,7 +33,7 @@ #define _SYS_CONDVAR_H_ typedef struct kcondvar { - void *cv_opaque[3]; + void *cv_opaque[2]; } kcondvar_t; #ifdef _KERNEL Index: src/sys/sys/lwp.h diff -u src/sys/sys/lwp.h:1.202 src/sys/sys/lwp.h:1.203 --- src/sys/sys/lwp.h:1.202 Sat Feb 15 18:12:15 2020 +++ src/sys/sys/lwp.h Thu Mar 26 19:46:42 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: lwp.h,v 1.202 2020/02/15 18:12:15 ad Exp $ */ +/* $NetBSD: lwp.h,v 1.203 2020/03/26 19:46:42 ad Exp $ */ /* * Copyright (c) 2001, 2006, 2007, 2008, 2009, 2010, 2019, 2020 @@ -125,7 +125,7 @@ struct lwp { /* Synchronisation. */ struct turnstile *l_ts; /* l: current turnstile */ struct syncobj *l_syncobj; /* l: sync object operations set */ - TAILQ_ENTRY(lwp) l_sleepchain; /* l: sleep queue */ + LIST_ENTRY(lwp) l_sleepchain; /* l: sleep queue */ wchan_t l_wchan; /* l: sleep address */ const char *l_wmesg; /* l: reason for sleep */ struct sleepq *l_sleepq; /* l: current sleep queue */ Index: src/sys/sys/sleepq.h diff -u src/sys/sys/sleepq.h:1.27 src/sys/sys/sleepq.h:1.28 --- src/sys/sys/sleepq.h:1.27 Mon Dec 16 19:43:36 2019 +++ src/sys/sys/sleepq.h Thu Mar 26 19:46:42 2020 @@ -1,7 +1,8 @@ -/* $NetBSD: sleepq.h,v 1.27 2019/12/16 19:43:36 ad Exp $ */ +/* $NetBSD: sleepq.h,v 1.28 2020/03/26 19:46:42 ad Exp $ */ /*- - * Copyright (c) 2002, 2006, 2007, 2008, 2009, 2019 The NetBSD Foundation, Inc. + * Copyright (c) 2002, 2006, 2007, 2008, 2009, 2019, 2020 + * The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -49,7 +50,7 @@ #define SLEEPTAB_HASH_MASK (SLEEPTAB_HASH_SIZE - 1) #define SLEEPTAB_HASH(wchan) (((uintptr_t)(wchan) >> 8) & SLEEPTAB_HASH_MASK) -TAILQ_HEAD(sleepq, lwp); +LIST_HEAD(sleepq, lwp); typedef struct sleepq sleepq_t; @@ -169,7 +170,7 @@ typedef struct tschain tschain_t; ((ts)->ts_waiters[TS_READER_Q] + \ (ts)->ts_waiters[TS_WRITER_Q]) -#define TS_FIRST(ts, q) (TAILQ_FIRST(&(ts)->ts_sleepq[(q)])) +#define TS_FIRST(ts, q) (LIST_FIRST(&(ts)->ts_sleepq[(q)])) #ifdef _KERNEL