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