xref: /netbsd/sys/sys/sleepq.h (revision 0a0fafcb)
1 /*	$NetBSD: sleepq.h,v 1.36 2022/10/26 23:24:59 riastradh Exp $	*/
2 
3 /*-
4  * Copyright (c) 2002, 2006, 2007, 2008, 2009, 2019, 2020
5  *     The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Jason R. Thorpe and Andrew Doran.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef	_SYS_SLEEPQ_H_
34 #define	_SYS_SLEEPQ_H_
35 
36 #include <sys/lwp.h>
37 #include <sys/mutex.h>
38 #include <sys/pool.h>
39 #include <sys/queue.h>
40 #include <sys/sched.h>
41 #include <sys/syncobj.h>
42 #include <sys/param.h>
43 
44 /*
45  * Generic sleep queues.
46  */
47 
48 typedef struct sleepq sleepq_t;
49 
50 void	sleepq_init(sleepq_t *);
51 void	sleepq_remove(sleepq_t *, lwp_t *);
52 void	sleepq_enqueue(sleepq_t *, wchan_t, const char *, struct syncobj *,
53 	    bool);
54 void	sleepq_transfer(lwp_t *, sleepq_t *, sleepq_t *, wchan_t, const char *,
55 	    struct syncobj *, kmutex_t *, bool);
56 void	sleepq_uncatch(lwp_t *);
57 void	sleepq_unsleep(lwp_t *, bool);
58 void	sleepq_timeout(void *);
59 void	sleepq_wake(sleepq_t *, wchan_t, u_int, kmutex_t *);
60 int	sleepq_abort(kmutex_t *, int);
61 void	sleepq_changepri(lwp_t *, pri_t);
62 void	sleepq_lendpri(lwp_t *, pri_t);
63 int	sleepq_block(int, bool, struct syncobj *);
64 
65 #ifdef _KERNEL
66 
67 #include <sys/kernel.h>
68 
69 typedef union {
70 	kmutex_t	lock;
71 	uint8_t		pad[COHERENCY_UNIT];
72 } sleepqlock_t;
73 
74 /*
75  * Return non-zero if it is unsafe to sleep.
76  *
77  * XXX This only exists because panic() is broken.
78  */
79 static __inline bool
sleepq_dontsleep(lwp_t * l)80 sleepq_dontsleep(lwp_t *l)
81 {
82 
83 	return cold || (doing_shutdown && (panicstr || CURCPU_IDLE_P()));
84 }
85 
86 /*
87  * Prepare to block on a sleep queue, after which any interlock can be
88  * safely released.
89  */
90 static __inline void
sleepq_enter(sleepq_t * sq,lwp_t * l,kmutex_t * mp)91 sleepq_enter(sleepq_t *sq, lwp_t *l, kmutex_t *mp)
92 {
93 
94 	/*
95 	 * Acquire the per-LWP mutex and lend it ours sleep queue lock.
96 	 * Once interlocked, we can release the kernel lock.
97 	 */
98 	lwp_lock(l);
99 	lwp_unlock_to(l, mp);
100 	KERNEL_UNLOCK_ALL(NULL, &l->l_biglocks);
101 }
102 
103 #endif
104 
105 #include <sys/sleeptab.h>
106 
107 #endif	/* _SYS_SLEEPQ_H_ */
108