Module Name: src Committed By: christos Date: Sun Nov 1 20:55:16 UTC 2020
Modified Files: src/sys/kern: kern_condvar.c src/sys/sys: sleepq.h Added Files: src/sys/sys: sleeptab.h Log Message: PR/55664: Ruslan Nikolaev: Split out sleepq guts and turnstiles not used in rump into a separate header file. Add a sleepq_destroy() empty hook. To generate a diff of this commit: cvs rdiff -u -r1.52 -r1.53 src/sys/kern/kern_condvar.c cvs rdiff -u -r1.32 -r1.33 src/sys/sys/sleepq.h cvs rdiff -u -r0 -r1.1 src/sys/sys/sleeptab.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.52 src/sys/kern/kern_condvar.c:1.53 --- src/sys/kern/kern_condvar.c:1.52 Sun May 10 23:59:33 2020 +++ src/sys/kern/kern_condvar.c Sun Nov 1 15:55:15 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_condvar.c,v 1.52 2020/05/11 03:59:33 riastradh Exp $ */ +/* $NetBSD: kern_condvar.c,v 1.53 2020/11/01 20:55:15 christos 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.52 2020/05/11 03:59:33 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_condvar.c,v 1.53 2020/11/01 20:55:15 christos Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -102,6 +102,7 @@ void cv_destroy(kcondvar_t *cv) { + sleepq_destroy(CV_SLEEPQ(cv)); #ifdef DIAGNOSTIC KASSERT(cv_is_valid(cv)); KASSERT(!cv_has_waiters(cv)); Index: src/sys/sys/sleepq.h diff -u src/sys/sys/sleepq.h:1.32 src/sys/sys/sleepq.h:1.33 --- src/sys/sys/sleepq.h:1.32 Thu Oct 22 20:25:45 2020 +++ src/sys/sys/sleepq.h Sun Nov 1 15:55:15 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: sleepq.h,v 1.32 2020/10/23 00:25:45 thorpej Exp $ */ +/* $NetBSD: sleepq.h,v 1.33 2020/11/01 20:55:15 christos Exp $ */ /*- * Copyright (c) 2002, 2006, 2007, 2008, 2009, 2019, 2020 @@ -45,20 +45,10 @@ * Generic sleep queues. */ -#define SLEEPTAB_HASH_SHIFT 7 -#define SLEEPTAB_HASH_SIZE (1 << SLEEPTAB_HASH_SHIFT) -#define SLEEPTAB_HASH_MASK (SLEEPTAB_HASH_SIZE - 1) -#define SLEEPTAB_HASH(wchan) (((uintptr_t)(wchan) >> 8) & SLEEPTAB_HASH_MASK) - -LIST_HEAD(sleepq, lwp); - typedef struct sleepq sleepq_t; -typedef struct sleeptab { - sleepq_t st_queue[SLEEPTAB_HASH_SIZE]; -} sleeptab_t; - void sleepq_init(sleepq_t *); +void sleepq_destroy(sleepq_t *); void sleepq_remove(sleepq_t *, lwp_t *); void sleepq_enqueue(sleepq_t *, wchan_t, const char *, struct syncobj *, bool); @@ -73,10 +63,6 @@ void sleepq_changepri(lwp_t *, pri_t); void sleepq_lendpri(lwp_t *, pri_t); int sleepq_block(int, bool); -void sleeptab_init(sleeptab_t *); - -extern sleeptab_t sleeptab; - #ifdef _KERNEL typedef union { kmutex_t lock; @@ -97,35 +83,6 @@ sleepq_dontsleep(lwp_t *l) } /* - * Find the correct sleep queue for the specified wait channel. This - * acquires and holds the per-queue interlock. - */ -static __inline sleepq_t * -sleeptab_lookup(sleeptab_t *st, wchan_t wchan, kmutex_t **mp) -{ - extern sleepqlock_t sleepq_locks[SLEEPTAB_HASH_SIZE]; - sleepq_t *sq; - u_int hash; - - hash = SLEEPTAB_HASH(wchan); - sq = &st->st_queue[hash]; - *mp = &sleepq_locks[hash].lock; - mutex_spin_enter(*mp); - return sq; -} - -static __inline kmutex_t * -sleepq_hashlock(wchan_t wchan) -{ - extern sleepqlock_t sleepq_locks[SLEEPTAB_HASH_SIZE]; - kmutex_t *mp; - - mp = &sleepq_locks[SLEEPTAB_HASH(wchan)].lock; - mutex_spin_enter(mp); - return mp; -} - -/* * Prepare to block on a sleep queue, after which any interlock can be * safely released. */ @@ -143,55 +100,6 @@ sleepq_enter(sleepq_t *sq, lwp_t *l, kmu } #endif -/* - * Turnstiles, specialized sleep queues for use by kernel locks. - */ - -typedef struct turnstile { - LIST_ENTRY(turnstile) ts_chain; /* link on hash chain */ - struct turnstile *ts_free; /* turnstile free list */ - wchan_t ts_obj; /* lock object */ - sleepq_t ts_sleepq[2]; /* sleep queues */ - u_int ts_waiters[2]; /* count of waiters */ - - /* priority inheritance */ - pri_t ts_eprio; - lwp_t *ts_inheritor; - SLIST_ENTRY(turnstile) ts_pichain; -} turnstile_t; - -LIST_HEAD(tschain, turnstile); - -typedef struct tschain tschain_t; - -#define TS_READER_Q 0 /* reader sleep queue */ -#define TS_WRITER_Q 1 /* writer sleep queue */ - -#define TS_WAITERS(ts, q) \ - (ts)->ts_waiters[(q)] - -#define TS_ALL_WAITERS(ts) \ - ((ts)->ts_waiters[TS_READER_Q] + \ - (ts)->ts_waiters[TS_WRITER_Q]) - -#define TS_FIRST(ts, q) (LIST_FIRST(&(ts)->ts_sleepq[(q)])) - -#ifdef _KERNEL - -void turnstile_init(void); -turnstile_t *turnstile_lookup(wchan_t); -void turnstile_ctor(turnstile_t *); -void turnstile_exit(wchan_t); -void turnstile_block(turnstile_t *, int, wchan_t, syncobj_t *); -void turnstile_wakeup(turnstile_t *, int, int, lwp_t *); -void turnstile_print(volatile void *, void (*)(const char *, ...) - __printflike(1, 2)); -void turnstile_unsleep(lwp_t *, bool); -void turnstile_changepri(lwp_t *, pri_t); - -extern struct pool turnstile_pool; -extern turnstile_t turnstile0; - -#endif /* _KERNEL */ +#include <sys/sleeptab.h> #endif /* _SYS_SLEEPQ_H_ */ Added files: Index: src/sys/sys/sleeptab.h diff -u /dev/null src/sys/sys/sleeptab.h:1.1 --- /dev/null Sun Nov 1 15:55:16 2020 +++ src/sys/sys/sleeptab.h Sun Nov 1 15:55:15 2020 @@ -0,0 +1,136 @@ +/* $NetBSD: sleeptab.h,v 1.1 2020/11/01 20:55:15 christos Exp $ */ + +/*- + * 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 + * by Jason R. Thorpe and Andrew Doran. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_SLEEPTAB_H_ +#define _SYS_SLEEPTAB_H_ + +#define SLEEPTAB_HASH_SHIFT 7 +#define SLEEPTAB_HASH_SIZE (1 << SLEEPTAB_HASH_SHIFT) +#define SLEEPTAB_HASH_MASK (SLEEPTAB_HASH_SIZE - 1) +#define SLEEPTAB_HASH(wchan) (((uintptr_t)(wchan) >> 8) & SLEEPTAB_HASH_MASK) + +LIST_HEAD(sleepq, lwp); + +typedef struct sleeptab { + sleepq_t st_queue[SLEEPTAB_HASH_SIZE]; +} sleeptab_t; + +void sleeptab_init(sleeptab_t *); + +extern sleeptab_t sleeptab; + +#ifdef _KERNEL +/* + * Find the correct sleep queue for the specified wait channel. This + * acquires and holds the per-queue interlock. + */ +static __inline sleepq_t * +sleeptab_lookup(sleeptab_t *st, wchan_t wchan, kmutex_t **mp) +{ + extern sleepqlock_t sleepq_locks[SLEEPTAB_HASH_SIZE]; + sleepq_t *sq; + u_int hash; + + hash = SLEEPTAB_HASH(wchan); + sq = &st->st_queue[hash]; + *mp = &sleepq_locks[hash].lock; + mutex_spin_enter(*mp); + return sq; +} + +static __inline kmutex_t * +sleepq_hashlock(wchan_t wchan) +{ + extern sleepqlock_t sleepq_locks[SLEEPTAB_HASH_SIZE]; + kmutex_t *mp; + + mp = &sleepq_locks[SLEEPTAB_HASH(wchan)].lock; + mutex_spin_enter(mp); + return mp; +} + +#define sleepq_destroy(a) + +#endif + +/* + * Turnstiles, specialized sleep queues for use by kernel locks. + */ + +typedef struct turnstile { + LIST_ENTRY(turnstile) ts_chain; /* link on hash chain */ + struct turnstile *ts_free; /* turnstile free list */ + wchan_t ts_obj; /* lock object */ + sleepq_t ts_sleepq[2]; /* sleep queues */ + u_int ts_waiters[2]; /* count of waiters */ + + /* priority inheritance */ + pri_t ts_eprio; + lwp_t *ts_inheritor; + SLIST_ENTRY(turnstile) ts_pichain; +} turnstile_t; + +LIST_HEAD(tschain, turnstile); + +typedef struct tschain tschain_t; + +#define TS_READER_Q 0 /* reader sleep queue */ +#define TS_WRITER_Q 1 /* writer sleep queue */ + +#define TS_WAITERS(ts, q) \ + (ts)->ts_waiters[(q)] + +#define TS_ALL_WAITERS(ts) \ + ((ts)->ts_waiters[TS_READER_Q] + \ + (ts)->ts_waiters[TS_WRITER_Q]) + +#define TS_FIRST(ts, q) (LIST_FIRST(&(ts)->ts_sleepq[(q)])) + +#ifdef _KERNEL + +void turnstile_init(void); +turnstile_t *turnstile_lookup(wchan_t); +void turnstile_ctor(turnstile_t *); +void turnstile_exit(wchan_t); +void turnstile_block(turnstile_t *, int, wchan_t, syncobj_t *); +void turnstile_wakeup(turnstile_t *, int, int, lwp_t *); +void turnstile_print(volatile void *, void (*)(const char *, ...) + __printflike(1, 2)); +void turnstile_unsleep(lwp_t *, bool); +void turnstile_changepri(lwp_t *, pri_t); + +extern struct pool turnstile_pool; +extern turnstile_t turnstile0; + +#endif /* _KERNEL */ + +#endif /* _SYS_SLEEPTAB_H_ */