1119026Sume/*-
266776Skris * SPDX-License-Identifier: (BSD-4-Clause AND BSD-2-Clause)
355163Sshin *
455163Sshin * Copyright (c) 1996, 1997
555163Sshin *      HD Associates, Inc.  All rights reserved.
662632Skris *
755163Sshin * Redistribution and use in source and binary forms, with or without
855163Sshin * modification, are permitted provided that the following conditions
955163Sshin * are met:
1055163Sshin * 1. Redistributions of source code must retain the above copyright
1155163Sshin *    notice, this list of conditions and the following disclaimer.
1255163Sshin * 2. Redistributions in binary form must reproduce the above copyright
1355163Sshin *    notice, this list of conditions and the following disclaimer in the
1455163Sshin *    documentation and/or other materials provided with the distribution.
1555163Sshin * 3. All advertising materials mentioning features or use of this software
1655163Sshin *    must display the following acknowledgement:
1755163Sshin *      This product includes software developed by HD Associates, Inc
1862632Skris *      and Jukka Antero Ukkonen.
1955163Sshin * 4. Neither the name of the author nor the names of any co-contributors
2055163Sshin *    may be used to endorse or promote products derived from this software
2155163Sshin *    without specific prior written permission.
2255163Sshin *
2355163Sshin * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES AND CONTRIBUTORS ``AS IS'' AND
2455163Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2555163Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2655163Sshin * ARE DISCLAIMED.  IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE
2755163Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2855163Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2955163Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3055163Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3155163Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3255163Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3355163Sshin * SUCH DAMAGE.
3455163Sshin */
35203387Sume
3655163Sshin/*-
3762632Skris * Copyright (c) 2002-2008, Jeffrey Roberson <jeff@freebsd.org>
38118909Sume * All rights reserved.
3955163Sshin *
4062632Skris * Redistribution and use in source and binary forms, with or without
4155163Sshin * modification, are permitted provided that the following conditions
42203387Sume * are met:
4355163Sshin * 1. Redistributions of source code must retain the above copyright
4455163Sshin *    notice unmodified, this list of conditions, and the following
4555163Sshin *    disclaimer.
46203387Sume * 2. Redistributions in binary form must reproduce the above copyright
4755163Sshin *    notice, this list of conditions and the following disclaimer in the
48203387Sume *    documentation and/or other materials provided with the distribution.
49203387Sume *
5055163Sshin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
5155163Sshin * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
5255163Sshin * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
5355163Sshin * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
5455163Sshin * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5555163Sshin * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
5655163Sshin * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
5755163Sshin * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5855163Sshin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
5966776Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60118916Sume */
61118916Sume
62118916Sume#ifndef _SCHED_H_
63118664Sume#define	_SCHED_H_
6455163Sshin
6555163Sshin#ifdef _KERNEL
66222732Shrs/*
67222732Shrs * General scheduling info.
68222732Shrs *
6955163Sshin * sched_load:
7055163Sshin *	Total runnable non-ithread threads in the system.
71118664Sume *
72118664Sume * sched_runnable:
73118664Sume *	Runnable threads for this processor.
74197141Shrs */
7566776Skrisint	sched_load(void);
7666776Skrisint	sched_rr_interval(void);
77118664Sumeint	sched_runnable(void);
78222732Shrs
79222732Shrs/*
8055163Sshin * Proc related scheduling hooks.
81147150Ssuz */
8262632Skrisvoid	sched_exit(struct proc *p, struct thread *childtd);
8362632Skrisvoid	sched_fork(struct thread *td, struct thread *childtd);
8462632Skrisvoid	sched_fork_exit(struct thread *td);
8555163Sshinvoid	sched_class(struct thread *td, int class);
86118664Sumevoid	sched_nice(struct proc *p, int nice);
87118910Sume
88118664Sume/*
89118664Sume * Threads are switched in and out, block on resources, have temporary
90118664Sume * priorities inherited from their procs, and use up cpu time.
9155163Sshin */
9255163Sshinvoid	sched_ap_entry(void);
9355163Sshinvoid	sched_exit_thread(struct thread *td, struct thread *child);
94222732Shrsu_int	sched_estcpu(struct thread *td);
95222732Shrsvoid	sched_fork_thread(struct thread *td, struct thread *child);
96124526Sumevoid	sched_ithread_prio(struct thread *td, u_char prio);
9755163Sshinvoid	sched_lend_prio(struct thread *td, u_char prio);
98222732Shrsvoid	sched_lend_user_prio(struct thread *td, u_char pri);
99124526Sumevoid	sched_lend_user_prio_cond(struct thread *td, u_char pri);
10055163Sshinfixpt_t	sched_pctcpu(struct thread *td);
10162632Skrisvoid	sched_prio(struct thread *td, u_char prio);
102173412Skevlovoid	sched_sleep(struct thread *td, int prio);
10362632Skrisvoid	sched_switch(struct thread *td, int flags);
104222732Shrsvoid	sched_throw(struct thread *td);
105173412Skevlovoid	sched_unlend_prio(struct thread *td, u_char prio);
106173412Skevlovoid	sched_user_prio(struct thread *td, u_char prio);
10755163Sshinvoid	sched_userret_slowpath(struct thread *td);
108124526Sume#ifdef	RACCT
109173412Skevlo#ifdef	SCHED_4BSD
110124526Sumefixpt_t	sched_pctcpu_delta(struct thread *td);
111222732Shrs#endif
11255163Sshin#endif
11355163Sshin
114124524Sumestatic inline void
11555163Sshinsched_userret(struct thread *td)
116118909Sume{
11755163Sshin
118204407Suqs	/*
119118916Sume	 * XXX we cheat slightly on the locking here to avoid locking in
120118916Sume	 * the usual case.  Setting td_priority here is essentially an
121118916Sume	 * incomplete workaround for not setting it properly elsewhere.
122118909Sume	 * Now that some interrupt handlers are threads, not setting it
123118909Sume	 * properly elsewhere can clobber it in the window between setting
124118909Sume	 * it here and returning to user mode, so don't waste time setting
125118916Sume	 * it perfectly here.
126118909Sume	 */
127222848Shrs	KASSERT((td->td_flags & TDF_BORROWING) == 0,
12855163Sshin	    ("thread with borrowed priority returning to userland"));
129222732Shrs	if (__predict_false(td->td_priority != td->td_user_pri))
130222732Shrs		sched_userret_slowpath(td);
131222732Shrs}
132222732Shrs
133222732Shrs/*
134222732Shrs * Threads are moved on and off of run queues
135222732Shrs */
136222732Shrsvoid	sched_add(struct thread *td, int flags);
137222732Shrsstruct thread *sched_choose(void);
138222848Shrsvoid	sched_clock(struct thread *td, int cnt);
139222848Shrsvoid	sched_idletd(void *);
14055163Sshinvoid	sched_preempt(struct thread *td);
14166776Skrisvoid	sched_relinquish(struct thread *td);
14266776Skrisvoid	sched_rem(struct thread *td);
14366776Skrisvoid	sched_wakeup(struct thread *td, int srqflags);
14466776Skris
14566776Skris/*
14666776Skris * Binding makes cpu affinity permanent while pinning is used to temporarily
14766776Skris * hold a thread on a particular CPU.
14866776Skris */
14966776Skrisvoid	sched_bind(struct thread *td, int cpu);
15066776Skrisstatic __inline void sched_pin(void);
15166776Skrisvoid	sched_unbind(struct thread *td);
15266776Skrisstatic __inline void sched_unpin(void);
15366776Skrisint	sched_is_bound(struct thread *td);
154124525Sumevoid	sched_affinity(struct thread *td);
155124525Sume
156124525Sume/*
15766776Skris * These procedures tell the process data structure allocation code how
15866776Skris * many bytes to actually allocate.
15966776Skris */
16066776Skrisint	sched_sizeof_proc(void);
16166776Skrisint	sched_sizeof_thread(void);
16266776Skris
163118661Sume/*
164118661Sume * This routine provides a consistent thread name for use with KTR graphing
165118661Sume * functions.
166222732Shrs */
167222732Shrschar	*sched_tdname(struct thread *td);
168222732Shrs#ifdef KTR
169222732Shrsvoid	sched_clear_tdname(struct thread *td);
170222732Shrs#endif
171222732Shrs
17266776Skrisstatic __inline void
173222732Shrssched_pin(void)
174222732Shrs{
17555163Sshin	curthread->td_pinned++;
17655163Sshin	atomic_interrupt_fence();
17755163Sshin}
17855163Sshin
17966776Skrisstatic __inline void
180119026Sumesched_unpin(void)
181222732Shrs{
182222732Shrs	atomic_interrupt_fence();
18366776Skris	curthread->td_pinned--;
18455163Sshin}
18555163Sshin
18655163Sshin/* sched_add arguments (formerly setrunqueue) */
18755163Sshin#define	SRQ_BORING	0x0000		/* No special circumstances. */
18855163Sshin#define	SRQ_YIELDING	0x0001		/* We are yielding (from mi_switch). */
18955163Sshin#define	SRQ_OURSELF	0x0002		/* It is ourself (from mi_switch). */
190118664Sume#define	SRQ_INTR	0x0004		/* It is probably urgent. */
191222848Shrs#define	SRQ_PREEMPTED	0x0008		/* has been preempted.. be kind */
19255163Sshin#define	SRQ_BORROWING	0x0010		/* Priority updated due to prio_lend */
193222848Shrs#define	SRQ_HOLD	0x0020		/* Return holding original td lock */
19455163Sshin#define	SRQ_HOLDTD	0x0040		/* Return holding td lock */
19555163Sshin
19655163Sshin/* Scheduler stats. */
19755163Sshin#ifdef SCHED_STATS
19855163SshinDPCPU_DECLARE(long, sched_switch_stats[SWT_COUNT]);
19955163Sshin
20055163Sshin#define	SCHED_STAT_DEFINE_VAR(name, ptr, descr)				\
201118661Sumestatic void name ## _add_proc(void *dummy __unused)			\
202118661Sume{									\
203118661Sume									\
204118661Sume	SYSCTL_ADD_PROC(NULL,						\
205222732Shrs	    SYSCTL_STATIC_CHILDREN(_kern_sched_stats), OID_AUTO,	\
206222732Shrs	    #name, CTLTYPE_LONG|CTLFLAG_RD|CTLFLAG_MPSAFE,		\
207222732Shrs	    ptr, 0, sysctl_dpcpu_long, "LU", descr);			\
208222732Shrs}									\
209222732ShrsSYSINIT(name, SI_SUB_LAST, SI_ORDER_MIDDLE, name ## _add_proc, NULL);
210222732Shrs
211222732Shrs#define	SCHED_STAT_DEFINE(name, descr)					\
212222732Shrs    DPCPU_DEFINE(unsigned long, name);					\
21362632Skris    SCHED_STAT_DEFINE_VAR(name, &DPCPU_NAME(name), descr)
214118664Sume/*
21555163Sshin * Sched stats are always incremented in critical sections so no atomic
21662632Skris * is necessary to increment them.
21755163Sshin */
218124525Sume#define SCHED_STAT_INC(var)     DPCPU_GET(var)++;
219124525Sume#else
220124525Sume#define	SCHED_STAT_DEFINE_VAR(name, descr, ptr)
221124525Sume#define	SCHED_STAT_DEFINE(name, descr)
222124525Sume#define SCHED_STAT_INC(var)			(void)0
223124525Sume#endif
224124525Sume
22555163Sshin/*
226124526Sume * Fixup scheduler state for proc0 and thread0
22755163Sshin */
228118910Sumevoid schedinit(void);
229124526Sume
23055163Sshin/*
231118914Sume * Fixup scheduler state for secondary APs
232118914Sume */
233118914Sumevoid schedinit_ap(void);
23462632Skris#endif /* _KERNEL */
23562632Skris
23662632Skris/* POSIX 1003.1b Process Scheduling */
23762632Skris
23862632Skris/*
23966776Skris * POSIX scheduling policies
240118914Sume */
241118914Sume#define SCHED_FIFO      1
24266776Skris#define SCHED_OTHER     2
243118916Sume#define SCHED_RR        3
244118916Sume
245118916Sumestruct sched_param {
246118916Sume        int     sched_priority;
24778064Sume};
248118916Sume
249118916Sume/*
250118916Sume * POSIX scheduling declarations for userland.
251118916Sume */
252118916Sume#ifndef _KERNEL
253118916Sume#include <sys/cdefs.h>
25478064Sume#include <sys/_timespec.h>
255118914Sume#include <sys/_types.h>
256118914Sume
25778064Sume#ifndef _PID_T_DECLARED
258118916Sumetypedef __pid_t         pid_t;
259118916Sume#define _PID_T_DECLARED
260118916Sume#endif
261118916Sume
26278064Sume__BEGIN_DECLS
26378064Sumeint     sched_get_priority_max(int);
264118916Sumeint     sched_get_priority_min(int);
26562632Skrisint     sched_getparam(pid_t, struct sched_param *);
266118916Sumeint     sched_getscheduler(pid_t);
267118909Sumeint     sched_rr_get_interval(pid_t, struct timespec *);
268118909Sumeint     sched_setparam(pid_t, const struct sched_param *);
269222732Shrsint     sched_setscheduler(pid_t, int, const struct sched_param *);
270222732Shrsint     sched_yield(void);
271118909Sume__END_DECLS
272118909Sume
273222732Shrs#endif
274222732Shrs#endif /* !_SCHED_H_ */
275118909Sume