aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/conf/files24
-rw-r--r--sys/kern/sched_4bsd.c101
-rw-r--r--sys/kern/sched_ns.h52
-rw-r--r--sys/kern/sched_shim.c1
-rw-r--r--sys/kern/sched_ule.c107
-rw-r--r--sys/sys/sched.h52
-rw-r--r--sys/tools/sched_impl_ns.awk38
7 files changed, 264 insertions, 111 deletions
diff --git a/sys/conf/files b/sys/conf/files
index cd38d5b9b4ae..3bc46035c816 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -3993,9 +3993,6 @@ kern/link_elf.c standard
kern/linker_if.m standard
kern/p1003_1b.c standard
kern/posix4_mib.c standard
-kern/sched_4bsd.c optional sched_4bsd
-kern/sched_shim.c standard
-kern/sched_ule.c optional sched_ule
kern/serdev_if.m standard
kern/stack_protector.c standard \
compile-with "${NORMAL_C:N-fstack-protector*}"
@@ -4719,6 +4716,27 @@ nlm/nlm_prot_svc.c optional nfslockd | nfsd
nlm/nlm_prot_xdr.c optional nfslockd | nfsd
nlm/sm_inter_xdr.c optional nfslockd | nfsd
+# Scheduler
+kern/sched_4bsd.c optional sched_4bsd
+sched_4bsd_ns.h optional sched_4bsd \
+ dependency "$S/kern/sched_ns.h $S/sys/sched.h \
+ $S/tools/sched_impl_ns.awk" \
+ compile-with "${CPP} -DSCHED_IMPLEMENTATION=4bsd \
+ $S/kern/sched_ns.h | \
+ ${AWK} -f $S/tools/sched_impl_ns.awk > ${.TARGET}" \
+ no-obj no-implicit-rule before-depend local \
+ clean "sched_4bsd_ns.h"
+kern/sched_ule.c optional sched_ule
+sched_ule_ns.h optional sched_ule \
+ dependency "$S/kern/sched_ns.h $S/sys/sched.h \
+ $S/tools/sched_impl_ns.awk" \
+ compile-with "${CPP} -DSCHED_IMPLEMENTATION=ule \
+ $S/kern/sched_ns.h | \
+ ${AWK} -f $S/tools/sched_impl_ns.awk > ${.TARGET}" \
+ no-obj no-implicit-rule before-depend local \
+ clean "sched_ule_ns.h"
+kern/sched_shim.c standard
+
# Linux Kernel Programming Interface
compat/linuxkpi/common/src/linux_80211.c optional compat_linuxkpi wlan \
compile-with "${LINUXKPI_C}"
diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
index 84d30b596d37..fc06ad8f5e1b 100644
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -48,6 +48,7 @@
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/runq.h>
+#define SCHED_IMPLEMENTATION 4bsd
#include <sys/sched.h>
#include <sys/sdt.h>
#include <sys/smp.h>
@@ -67,6 +68,12 @@
#endif
/*
+ * Namespacing for implementation functions to have same name as interface
+ * functions in the code while retaining namespaced symbols in the kernel ELF.
+ */
+#include "sched_4bsd_ns.h"
+
+/*
* INVERSE_ESTCPU_WEIGHT is only suitable for statclock() frequencies in
* the range 100-256 Hz (approximately).
*/
@@ -161,7 +168,7 @@ static struct kproc_desc sched_kp = {
};
static void
-sched_4bsd_sysinit(void)
+sched_sysinit(void)
{
kproc_start(&sched_kp);
}
@@ -640,7 +647,7 @@ resetpriority_thread(struct thread *td)
}
static void
-sched_4bsd_setup(void)
+sched_setup(void)
{
/*
* Decay 95% of `ts_pctcpu' in 60 seconds; see CCPU_SHIFT
@@ -660,7 +667,7 @@ sched_4bsd_setup(void)
* This routine determines time constants after stathz and hz are setup.
*/
static void
-sched_4bsd_initticks(void)
+sched_initticks(void)
{
realstathz = stathz ? stathz : hz;
@@ -677,7 +684,7 @@ sched_4bsd_initticks(void)
* proc0_init()
*/
static void
-sched_4bsd_init(void)
+sched_init(void)
{
/*
@@ -689,14 +696,14 @@ sched_4bsd_init(void)
}
static void
-sched_4bsd_init_ap(void)
+sched_init_ap(void)
{
/* Nothing needed. */
}
static bool
-sched_4bsd_runnable(void)
+sched_runnable(void)
{
#ifdef SMP
return (runq_not_empty(&runq_global) ||
@@ -707,7 +714,7 @@ sched_4bsd_runnable(void)
}
static int
-sched_4bsd_rr_interval(void)
+sched_rr_interval(void)
{
/* Convert sched_slice from stathz to hz. */
@@ -774,7 +781,7 @@ sched_clock_tick(struct thread *td)
}
static void
-sched_4bsd_clock(struct thread *td, int cnt)
+sched_clock(struct thread *td, int cnt)
{
for ( ; cnt > 0; cnt--)
@@ -785,7 +792,7 @@ sched_4bsd_clock(struct thread *td, int cnt)
* Charge child's scheduling CPU usage to parent.
*/
static void
-sched_4bsd_exit(struct proc *p, struct thread *td)
+sched_exit(struct proc *p, struct thread *td)
{
KTR_STATE1(KTR_SCHED, "thread", sched_tdname(td), "proc exit",
@@ -796,7 +803,7 @@ sched_4bsd_exit(struct proc *p, struct thread *td)
}
static void
-sched_4bsd_exit_thread(struct thread *td, struct thread *child)
+sched_exit_thread(struct thread *td, struct thread *child)
{
KTR_STATE1(KTR_SCHED, "thread", sched_tdname(child), "exit",
@@ -812,13 +819,13 @@ sched_4bsd_exit_thread(struct thread *td, struct thread *child)
}
static void
-sched_4bsd_fork(struct thread *td, struct thread *childtd)
+sched_fork(struct thread *td, struct thread *childtd)
{
sched_fork_thread(td, childtd);
}
static void
-sched_4bsd_fork_thread(struct thread *td, struct thread *childtd)
+sched_fork_thread(struct thread *td, struct thread *childtd)
{
struct td_sched *ts, *tsc;
@@ -837,7 +844,7 @@ sched_4bsd_fork_thread(struct thread *td, struct thread *childtd)
}
static void
-sched_4bsd_nice(struct proc *p, int nice)
+sched_nice(struct proc *p, int nice)
{
struct thread *td;
@@ -852,7 +859,7 @@ sched_4bsd_nice(struct proc *p, int nice)
}
static void
-sched_4bsd_class(struct thread *td, int class)
+sched_class(struct thread *td, int class)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
td->td_pri_class = class;
@@ -891,7 +898,7 @@ sched_priority(struct thread *td, u_char prio)
* priority.
*/
static void
-sched_4bsd_lend_prio(struct thread *td, u_char prio)
+sched_lend_prio(struct thread *td, u_char prio)
{
td->td_flags |= TDF_BORROWING;
@@ -907,7 +914,7 @@ sched_4bsd_lend_prio(struct thread *td, u_char prio)
* of prio.
*/
static void
-sched_4bsd_unlend_prio(struct thread *td, u_char prio)
+sched_unlend_prio(struct thread *td, u_char prio)
{
u_char base_pri;
@@ -924,7 +931,7 @@ sched_4bsd_unlend_prio(struct thread *td, u_char prio)
}
static void
-sched_4bsd_prio(struct thread *td, u_char prio)
+sched_prio(struct thread *td, u_char prio)
{
u_char oldprio;
@@ -951,7 +958,7 @@ sched_4bsd_prio(struct thread *td, u_char prio)
}
static void
-sched_4bsd_ithread_prio(struct thread *td, u_char prio)
+sched_ithread_prio(struct thread *td, u_char prio)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
MPASS(td->td_pri_class == PRI_ITHD);
@@ -960,7 +967,7 @@ sched_4bsd_ithread_prio(struct thread *td, u_char prio)
}
static void
-sched_4bsd_user_prio(struct thread *td, u_char prio)
+sched_user_prio(struct thread *td, u_char prio)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
@@ -971,7 +978,7 @@ sched_4bsd_user_prio(struct thread *td, u_char prio)
}
static void
-sched_4bsd_lend_user_prio(struct thread *td, u_char prio)
+sched_lend_user_prio(struct thread *td, u_char prio)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
@@ -987,7 +994,7 @@ sched_4bsd_lend_user_prio(struct thread *td, u_char prio)
* Like the above but first check if there is anything to do.
*/
static void
-sched_4bsd_lend_user_prio_cond(struct thread *td, u_char prio)
+sched_lend_user_prio_cond(struct thread *td, u_char prio)
{
if (td->td_lend_user_pri == prio)
@@ -999,7 +1006,7 @@ sched_4bsd_lend_user_prio_cond(struct thread *td, u_char prio)
}
static void
-sched_4bsd_sleep(struct thread *td, int pri)
+sched_sleep(struct thread *td, int pri)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
@@ -1010,7 +1017,7 @@ sched_4bsd_sleep(struct thread *td, int pri)
}
static void
-sched_4bsd_switch(struct thread *td, int flags)
+sched_switch(struct thread *td, int flags)
{
struct thread *newtd;
struct mtx *tmtx;
@@ -1143,7 +1150,7 @@ sched_4bsd_switch(struct thread *td, int flags)
}
static void
-sched_4bsd_wakeup(struct thread *td, int srqflags)
+sched_wakeup(struct thread *td, int srqflags)
{
struct td_sched *ts;
@@ -1318,7 +1325,7 @@ sched_pickcpu(struct thread *td)
#endif
static void
-sched_4bsd_add(struct thread *td, int flags)
+sched_add(struct thread *td, int flags)
#ifdef SMP
{
cpuset_t tidlemsk;
@@ -1465,7 +1472,7 @@ sched_4bsd_add(struct thread *td, int flags)
#endif /* SMP */
static void
-sched_4bsd_rem(struct thread *td)
+sched_rem(struct thread *td)
{
struct td_sched *ts;
@@ -1495,7 +1502,7 @@ sched_4bsd_rem(struct thread *td)
* slot.
*/
static struct thread *
-sched_4bsd_choose(void)
+sched_choose(void)
{
struct thread *td;
struct runq *runq;
@@ -1540,7 +1547,7 @@ sched_4bsd_choose(void)
}
static void
-sched_4bsd_preempt(struct thread *td)
+sched_preempt(struct thread *td)
{
int flags;
@@ -1558,7 +1565,7 @@ sched_4bsd_preempt(struct thread *td)
}
static void
-sched_4bsd_userret_slowpath(struct thread *td)
+sched_userret_slowpath(struct thread *td)
{
thread_lock(td);
@@ -1568,7 +1575,7 @@ sched_4bsd_userret_slowpath(struct thread *td)
}
static void
-sched_4bsd_bind(struct thread *td, int cpu)
+sched_bind(struct thread *td, int cpu)
{
#ifdef SMP
struct td_sched *ts = td_get_sched(td);
@@ -1589,7 +1596,7 @@ sched_4bsd_bind(struct thread *td, int cpu)
}
static void
-sched_4bsd_unbind(struct thread* td)
+sched_unbind(struct thread* td)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
KASSERT(td == curthread, ("sched_unbind: can only bind curthread"));
@@ -1597,39 +1604,39 @@ sched_4bsd_unbind(struct thread* td)
}
static int
-sched_4bsd_is_bound(struct thread *td)
+sched_is_bound(struct thread *td)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
return (td->td_flags & TDF_BOUND);
}
static void
-sched_4bsd_relinquish(struct thread *td)
+sched_relinquish(struct thread *td)
{
thread_lock(td);
mi_switch(SW_VOL | SWT_RELINQUISH);
}
static int
-sched_4bsd_load(void)
+sched_load(void)
{
return (sched_tdcnt);
}
static int
-sched_4bsd_sizeof_proc(void)
+sched_sizeof_proc(void)
{
return (sizeof(struct proc));
}
static int
-sched_4bsd_sizeof_thread(void)
+sched_sizeof_thread(void)
{
return (sizeof(struct thread) + sizeof(struct td_sched));
}
static fixpt_t
-sched_4bsd_pctcpu(struct thread *td)
+sched_pctcpu(struct thread *td)
{
struct td_sched *ts;
@@ -1639,7 +1646,7 @@ sched_4bsd_pctcpu(struct thread *td)
}
static u_int
-sched_4bsd_estcpu(struct thread *td)
+sched_estcpu(struct thread *td)
{
return (td_get_sched(td)->ts_estcpu);
@@ -1649,7 +1656,7 @@ sched_4bsd_estcpu(struct thread *td)
* The actual idle process.
*/
static void
-sched_4bsd_idletd(void *dummy)
+sched_idletd(void *dummy)
{
struct pcpuidlestat *stat;
@@ -1691,7 +1698,7 @@ sched_throw_tail(struct thread *td)
* A CPU is entering for the first time.
*/
static void
-sched_4bsd_ap_entry(void)
+sched_ap_entry(void)
{
/*
@@ -1715,7 +1722,7 @@ sched_4bsd_ap_entry(void)
* A thread is exiting.
*/
static void
-sched_4bsd_throw(struct thread *td)
+sched_throw(struct thread *td)
{
MPASS(td != NULL);
@@ -1729,7 +1736,7 @@ sched_4bsd_throw(struct thread *td)
}
static void
-sched_4bsd_fork_exit(struct thread *td)
+sched_fork_exit(struct thread *td)
{
/*
@@ -1748,7 +1755,7 @@ sched_4bsd_fork_exit(struct thread *td)
}
static char *
-sched_4bsd_tdname(struct thread *td)
+sched_tdname(struct thread *td)
{
#ifdef KTR
struct td_sched *ts;
@@ -1764,7 +1771,7 @@ sched_4bsd_tdname(struct thread *td)
}
static void
-sched_4bsd_clear_tdname(struct thread *td)
+sched_clear_tdname(struct thread *td)
{
#ifdef KTR
struct td_sched *ts;
@@ -1775,7 +1782,7 @@ sched_4bsd_clear_tdname(struct thread *td)
}
static void
-sched_4bsd_affinity(struct thread *td)
+sched_affinity(struct thread *td)
{
#ifdef SMP
struct td_sched *ts;
@@ -1838,9 +1845,9 @@ sched_4bsd_affinity(struct thread *td)
}
static int
-sched_4bsd_find_l2_neighbor(int cpu)
+sched_find_l2_neighbor(int cpu)
{
return (-1);
}
-DECLARE_SCHEDULER(4bsd, "4BSD");
+DECLARE_SCHEDULER("4BSD");
diff --git a/sys/kern/sched_ns.h b/sys/kern/sched_ns.h
new file mode 100644
index 000000000000..0c71f4350fbc
--- /dev/null
+++ b/sys/kern/sched_ns.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2026 The FreeBSD Foundation
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * This software was developed by Olivier Certner <olce@FreeBSD.org>
+ * at Kumacom SARL under sponsorship from the FreeBSD Foundation.
+ */
+
+/*
+ * This file serves to generate a namespacing header for scheduler
+ * implementations.
+ *
+ * During build, it is pre-processed with CPP and only the (expanded) lines
+ * between the __START__ and __END__ lines below remain in the
+ * implementation-specific namespacing header.
+ *
+ * Lines produced between __START__ and __END__ below look like:
+ *
+ * # define sched_clock sched_ule_clock __NL__
+ * # define sched_switch sched_ule_switch __NL__
+ *
+ * and the build machinery substitutes __NL__ by newlines so the final result
+ * can be included and its lines recognized as '#define' preprocessing
+ * directives.
+ *
+ * A line between __START__ and __END__ starting with __CHECK_IMPLEMENTATION__
+ * is treated specially and generates code that checks whether
+ * SCHED_IMPLEMENTATION is the same as the value passed as the first argument
+ * (which is that of SCHED_IMPLEMENTATION here).
+ *
+ * See files 'sys/conf/files' and 'sys/tools/sched_impl_ns.awk' for the
+ * machinery.
+ */
+
+#define _KERNEL
+#include <sys/cdefs.h>
+#include <sys/sched.h>
+
+#define _SCHED_IMPL_DEFINE(args, ret_type, fn, ...) \
+ _SCHED_ITF_ARG2 args define SCHED_ITF_FUNCTION_NAME(fn) \
+ SCHED_ITF_IMPL_FUNCTION_NAME(_SCHED_ITF_ARG1 args, fn) \
+ __NL__
+
+#ifndef SCHED_IMPLEMENTATION
+#error SCHED_IMPLEMENTATION must be defined (via sys/conf/files)
+#endif
+
+__START__
+__CHECK_IMPLEMENTATION__ SCHED_IMPLEMENTATION
+SCHED_ITF_NOCOMMON(_SCHED_IMPL_DEFINE, SCHED_IMPLEMENTATION, #)
+__END__
diff --git a/sys/kern/sched_shim.c b/sys/kern/sched_shim.c
index 8fdd12e5f84d..e79221e9f771 100644
--- a/sys/kern/sched_shim.c
+++ b/sys/kern/sched_shim.c
@@ -15,6 +15,7 @@
#include <sys/proc.h>
#include <sys/runq.h>
#include <sys/sbuf.h>
+#define SCHED_SHIM
#include <sys/sched.h>
#include <sys/smp.h>
#include <sys/sysctl.h>
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index 96acd31d6419..44c787b13ece 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -52,6 +52,7 @@
#include <sys/resource.h>
#include <sys/resourcevar.h>
#include <sys/runq.h>
+#define SCHED_IMPLEMENTATION ule
#include <sys/sched.h>
#include <sys/sdt.h>
#include <sys/smp.h>
@@ -75,6 +76,12 @@
#include <machine/cpu.h>
#include <machine/smp.h>
+/*
+ * Namespacing for implementation functions to have same name as interface
+ * functions in the code while retaining namespaced symbols in the kernel ELF.
+ */
+#include "sched_ule_ns.h"
+
#define TS_NAME_LEN (MAXCOMLEN + sizeof(" td ") + sizeof(__XSTRING(UINT_MAX)))
#define TDQ_NAME_LEN (sizeof("sched lock ") + sizeof(__XSTRING(MAXCPU)))
#define TDQ_LOADNAME_LEN (sizeof("CPU ") + sizeof(__XSTRING(MAXCPU)) - 1 + sizeof(" load"))
@@ -1637,7 +1644,7 @@ sched_setup_smp(void)
* information.
*/
static void
-sched_ule_setup(void)
+sched_setup(void)
{
struct tdq *tdq;
@@ -1662,7 +1669,7 @@ sched_ule_setup(void)
*/
/* ARGSUSED */
static void
-sched_ule_initticks(void)
+sched_initticks(void)
{
int incr;
@@ -1886,7 +1893,7 @@ sched_interact_fork(struct thread *td)
* Called from proc0_init() to setup the scheduler fields.
*/
static void
-sched_ule_init(void)
+sched_init(void)
{
struct td_sched *ts0;
@@ -1911,7 +1918,7 @@ sched_ule_init(void)
* after sched_init_ap().
*/
static void
-sched_ule_init_ap(void)
+sched_init_ap(void)
{
#ifdef SMP
@@ -1926,7 +1933,7 @@ sched_ule_init_ap(void)
* at most sched_slice stathz ticks.
*/
static int
-sched_ule_rr_interval(void)
+sched_rr_interval(void)
{
/* Convert sched_slice from stathz to hz. */
@@ -2046,7 +2053,7 @@ sched_thread_priority(struct thread *td, u_char prio)
* priority.
*/
static void
-sched_ule_lend_prio(struct thread *td, u_char prio)
+sched_lend_prio(struct thread *td, u_char prio)
{
td->td_flags |= TDF_BORROWING;
@@ -2062,7 +2069,7 @@ sched_ule_lend_prio(struct thread *td, u_char prio)
* of prio.
*/
static void
-sched_ule_unlend_prio(struct thread *td, u_char prio)
+sched_unlend_prio(struct thread *td, u_char prio)
{
u_char base_pri;
@@ -2082,7 +2089,7 @@ sched_ule_unlend_prio(struct thread *td, u_char prio)
* Standard entry for setting the priority to an absolute value.
*/
static void
-sched_ule_prio(struct thread *td, u_char prio)
+sched_prio(struct thread *td, u_char prio)
{
u_char oldprio;
@@ -2112,7 +2119,7 @@ sched_ule_prio(struct thread *td, u_char prio)
* Set the base interrupt thread priority.
*/
static void
-sched_ule_ithread_prio(struct thread *td, u_char prio)
+sched_ithread_prio(struct thread *td, u_char prio)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
MPASS(td->td_pri_class == PRI_ITHD);
@@ -2124,7 +2131,7 @@ sched_ule_ithread_prio(struct thread *td, u_char prio)
* Set the base user priority, does not effect current running priority.
*/
static void
-sched_ule_user_prio(struct thread *td, u_char prio)
+sched_user_prio(struct thread *td, u_char prio)
{
td->td_base_user_pri = prio;
@@ -2134,7 +2141,7 @@ sched_ule_user_prio(struct thread *td, u_char prio)
}
static void
-sched_ule_lend_user_prio(struct thread *td, u_char prio)
+sched_lend_user_prio(struct thread *td, u_char prio)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
@@ -2150,7 +2157,7 @@ sched_ule_lend_user_prio(struct thread *td, u_char prio)
* Like the above but first check if there is anything to do.
*/
static void
-sched_ule_lend_user_prio_cond(struct thread *td, u_char prio)
+sched_lend_user_prio_cond(struct thread *td, u_char prio)
{
if (td->td_lend_user_pri == prio)
@@ -2322,7 +2329,7 @@ thread_unblock_switch(struct thread *td, struct mtx *mtx)
* be assigned elsewhere via binding.
*/
static void
-sched_ule_switch(struct thread *td, int flags)
+sched_switch(struct thread *td, int flags)
{
struct thread *newtd;
struct tdq *tdq;
@@ -2461,7 +2468,7 @@ sched_ule_switch(struct thread *td, int flags)
* Adjust thread priorities as a result of a nice request.
*/
static void
-sched_ule_nice(struct proc *p, int nice)
+sched_nice(struct proc *p, int nice)
{
struct thread *td;
@@ -2480,7 +2487,7 @@ sched_ule_nice(struct proc *p, int nice)
* Record the sleep time for the interactivity scorer.
*/
static void
-sched_ule_sleep(struct thread *td, int prio)
+sched_sleep(struct thread *td, int prio)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
@@ -2501,7 +2508,7 @@ sched_ule_sleep(struct thread *td, int prio)
* Requires the thread lock on entry, drops on exit.
*/
static void
-sched_ule_wakeup(struct thread *td, int srqflags)
+sched_wakeup(struct thread *td, int srqflags)
{
struct td_sched *ts;
int slptick;
@@ -2541,7 +2548,7 @@ sched_ule_wakeup(struct thread *td, int srqflags)
* priority.
*/
static void
-sched_ule_fork(struct thread *td, struct thread *child)
+sched_fork(struct thread *td, struct thread *child)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
sched_pctcpu_update(td_get_sched(td), 1);
@@ -2560,7 +2567,7 @@ sched_ule_fork(struct thread *td, struct thread *child)
* Fork a new thread, may be within the same process.
*/
static void
-sched_ule_fork_thread(struct thread *td, struct thread *child)
+sched_fork_thread(struct thread *td, struct thread *child)
{
struct td_sched *ts;
struct td_sched *ts2;
@@ -2606,7 +2613,7 @@ sched_ule_fork_thread(struct thread *td, struct thread *child)
* Adjust the priority class of a thread.
*/
static void
-sched_ule_class(struct thread *td, int class)
+sched_class(struct thread *td, int class)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
@@ -2619,7 +2626,7 @@ sched_ule_class(struct thread *td, int class)
* Return some of the child's priority and interactivity to the parent.
*/
static void
-sched_ule_exit(struct proc *p, struct thread *child)
+sched_exit(struct proc *p, struct thread *child)
{
struct thread *td;
@@ -2637,7 +2644,7 @@ sched_ule_exit(struct proc *p, struct thread *child)
* causes new processes spawned by it to receive worse scores immediately.
*/
static void
-sched_ule_exit_thread(struct thread *td, struct thread *child)
+sched_exit_thread(struct thread *td, struct thread *child)
{
KTR_STATE1(KTR_SCHED, "thread", sched_tdname(child), "thread exit",
@@ -2655,7 +2662,7 @@ sched_ule_exit_thread(struct thread *td, struct thread *child)
}
static void
-sched_ule_preempt(struct thread *td)
+sched_preempt(struct thread *td)
{
struct tdq *tdq;
int flags;
@@ -2687,7 +2694,7 @@ sched_ule_preempt(struct thread *td)
* to static priorities in msleep() or similar.
*/
static void
-sched_ule_userret_slowpath(struct thread *td)
+sched_userret_slowpath(struct thread *td)
{
thread_lock(td);
@@ -2714,7 +2721,7 @@ td_slice(struct thread *td, struct tdq *tdq)
* and interrupt threads.
*/
static void
-sched_ule_clock(struct thread *td, int cnt)
+sched_clock(struct thread *td, int cnt)
{
struct tdq *tdq;
struct td_sched *ts;
@@ -2800,7 +2807,7 @@ sched_ule_clock(struct thread *td, int cnt)
}
static u_int
-sched_ule_estcpu(struct thread *td __unused)
+sched_estcpu(struct thread *td __unused)
{
return (0);
@@ -2811,7 +2818,7 @@ sched_ule_estcpu(struct thread *td __unused)
* cooperative idle threads.
*/
static bool
-sched_ule_runnable(void)
+sched_runnable(void)
{
struct tdq *tdq;
@@ -2824,7 +2831,7 @@ sched_ule_runnable(void)
* the run-queue while running however the load remains.
*/
static struct thread *
-sched_ule_choose(void)
+sched_choose(void)
{
struct thread *td;
struct tdq *tdq;
@@ -2901,7 +2908,7 @@ tdq_add(struct tdq *tdq, struct thread *td, int flags)
* Requires the thread lock on entry, drops on exit.
*/
static void
-sched_ule_add(struct thread *td, int flags)
+sched_add(struct thread *td, int flags)
{
struct tdq *tdq;
#ifdef SMP
@@ -2961,7 +2968,7 @@ sched_ule_add(struct thread *td, int flags)
* exit by calling sched_exit_thread() and sched_throw() themselves.
*/
static void
-sched_ule_rem(struct thread *td)
+sched_rem(struct thread *td)
{
struct tdq *tdq;
@@ -2984,7 +2991,7 @@ sched_ule_rem(struct thread *td)
* Fetch cpu utilization information. Updates on demand.
*/
static fixpt_t
-sched_ule_pctcpu(struct thread *td)
+sched_pctcpu(struct thread *td)
{
struct td_sched *ts;
u_int len;
@@ -3006,7 +3013,7 @@ sched_ule_pctcpu(struct thread *td)
* cpumask.
*/
static void
-sched_ule_affinity(struct thread *td)
+sched_affinity(struct thread *td)
{
#ifdef SMP
struct td_sched *const ts = td_get_sched(td);
@@ -3039,7 +3046,7 @@ sched_ule_affinity(struct thread *td)
* Bind a thread to a target cpu.
*/
static void
-sched_ule_bind(struct thread *td, int cpu)
+sched_bind(struct thread *td, int cpu)
{
struct td_sched *ts;
@@ -3063,7 +3070,7 @@ sched_ule_bind(struct thread *td, int cpu)
* Release a bound thread.
*/
static void
-sched_ule_unbind(struct thread *td)
+sched_unbind(struct thread *td)
{
struct td_sched *ts;
@@ -3077,7 +3084,7 @@ sched_ule_unbind(struct thread *td)
}
static int
-sched_ule_is_bound(struct thread *td)
+sched_is_bound(struct thread *td)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
return (td_get_sched(td)->ts_flags & TSF_BOUND);
@@ -3087,7 +3094,7 @@ sched_ule_is_bound(struct thread *td)
* Basic yield call.
*/
static void
-sched_ule_relinquish(struct thread *td)
+sched_relinquish(struct thread *td)
{
thread_lock(td);
mi_switch(SW_VOL | SWT_RELINQUISH);
@@ -3097,7 +3104,7 @@ sched_ule_relinquish(struct thread *td)
* Return the total system load.
*/
static int
-sched_ule_load(void)
+sched_load(void)
{
#ifdef SMP
int total;
@@ -3113,13 +3120,13 @@ sched_ule_load(void)
}
static int
-sched_ule_sizeof_proc(void)
+sched_sizeof_proc(void)
{
return (sizeof(struct proc));
}
static int
-sched_ule_sizeof_thread(void)
+sched_sizeof_thread(void)
{
return (sizeof(struct thread) + sizeof(struct td_sched));
}
@@ -3135,7 +3142,7 @@ sched_ule_sizeof_thread(void)
* The actual idle process.
*/
static void
-sched_ule_idletd(void *dummy)
+sched_idletd(void *dummy)
{
struct thread *td;
struct tdq *tdq;
@@ -3238,7 +3245,7 @@ sched_throw_grab(struct tdq *tdq)
* A CPU is entering for the first time.
*/
static void
-sched_ule_ap_entry(void)
+sched_ap_entry(void)
{
struct thread *newtd;
struct tdq *tdq;
@@ -3268,7 +3275,7 @@ sched_ule_ap_entry(void)
* A thread is exiting.
*/
static void
-sched_ule_throw(struct thread *td)
+sched_throw(struct thread *td)
{
struct thread *newtd;
struct tdq *tdq;
@@ -3299,7 +3306,7 @@ sched_ule_throw(struct thread *td)
* let fork do the rest of the work.
*/
static void
-sched_ule_fork_exit(struct thread *td)
+sched_fork_exit(struct thread *td)
{
struct tdq *tdq;
int cpuid;
@@ -3325,7 +3332,7 @@ sched_ule_fork_exit(struct thread *td)
* Create on first use to catch odd startup conditions.
*/
static char *
-sched_ule_tdname(struct thread *td)
+sched_tdname(struct thread *td)
{
#ifdef KTR
struct td_sched *ts;
@@ -3341,7 +3348,7 @@ sched_ule_tdname(struct thread *td)
}
static void
-sched_ule_clear_tdname(struct thread *td)
+sched_clear_tdname(struct thread *td)
{
#ifdef KTR
struct td_sched *ts;
@@ -3352,13 +3359,13 @@ sched_ule_clear_tdname(struct thread *td)
}
static void
-sched_ule_sysinit(void)
+sched_sysinit(void)
{
}
#ifdef SMP
static int
-sched_ule_find_child_with_core(int cpu, struct cpu_group *grp)
+sched_find_child_with_core(int cpu, struct cpu_group *grp)
{
int i;
@@ -3375,7 +3382,7 @@ sched_ule_find_child_with_core(int cpu, struct cpu_group *grp)
}
static int
-sched_ule_find_l2_neighbor(int cpu)
+sched_find_l2_neighbor(int cpu)
{
struct cpu_group *grp;
int i;
@@ -3388,7 +3395,7 @@ sched_ule_find_l2_neighbor(int cpu)
* Find the smallest CPU group that contains the given core.
*/
i = 0;
- while ((i = sched_ule_find_child_with_core(cpu, grp)) != -1) {
+ while ((i = sched_find_child_with_core(cpu, grp)) != -1) {
/*
* If the smallest group containing the given CPU has less
* than two members, we conclude the given CPU has no
@@ -3417,7 +3424,7 @@ sched_ule_find_l2_neighbor(int cpu)
}
#else
static int
-sched_ule_find_l2_neighbor(int cpu)
+sched_find_l2_neighbor(int cpu)
{
return (-1);
}
@@ -3505,4 +3512,4 @@ SYSCTL_INT(_kern_sched_ule, OID_AUTO, always_steal, CTLFLAG_RWTUN,
"Always run the stealer from the idle thread");
#endif
-DECLARE_SCHEDULER(ule, "ULE");
+DECLARE_SCHEDULER("ULE");
diff --git a/sys/sys/sched.h b/sys/sys/sched.h
index 75c56a864076..3a88c03d2d60 100644
--- a/sys/sys/sched.h
+++ b/sys/sys/sched.h
@@ -317,6 +317,8 @@
*/
#define _SCHED_ITF_ARG1(a0, ...) \
a0
+#define _SCHED_ITF_ARG2(a0, a1, ...) \
+ a1
#define _SCHED_ITF_ARG9(a0, a1, a2, a3, a4, a5, a6, a7, a8, ...) \
a8
#define _SCHED_ITF_NARGS(...) \
@@ -362,16 +364,18 @@
__CONCAT(fn, _impl)
#define SCHED_ITF_FUNCTION_NAME(fn) \
__CONCAT(sched_, fn)
-#define _SCHED_ITF_IMPL_FUNCTION_NAME(sched_name, fn) \
+#define SCHED_ITF_IMPL_FUNCTION_NAME(sched_name, fn) \
SCHED_ITF_FUNCTION_NAME(__CONCAT(__CONCAT(sched_name, _), \
fn))
-/*
- * C declaration of first part of interface functions.
- */
struct proc;
struct thread;
+#ifndef SCHED_IMPLEMENTATION
+
+/*
+ * C declaration of first part of interface functions.
+ */
/* Eliding argument names to avoid collisions with C++ keywords. */
#define _SCHED_ITF_FUN(args, ret_type, fn, ...) \
ret_type \
@@ -381,10 +385,29 @@ SCHED_ITF_DISPATCH(_SCHED_ITF_FUN, );
SCHED_ITF_WRAP(_SCHED_ITF_FUN, );
#undef _SCHED_ITF_FUN
+#else /* SCHED_IMPLEMENTATION */
+
+/*
+ * C declarations for implementation functions.
+ *
+ * SCHED_IMPLEMENTATION must be defined to the scheduler name as used in
+ * variable names (i.e., lower case, such as 4bsd or ule).
+ */
+#define _SCHED_ITF_FUN(args, ret_type, fn, ...) \
+ static ret_type \
+ SCHED_ITF_IMPL_FUNCTION_NAME(_SCHED_ITF_ARG1 args, fn) \
+ (SCHED_ITF_ARGS_PROTO_NAME(__VA_ARGS__));
+SCHED_ITF_NOCOMMON(_SCHED_ITF_FUN, SCHED_IMPLEMENTATION)
+#undef _SCHED_ITF_FUN
+
+#endif /* !SCHED_IMPLEMENTATION */
+
/*
* Common functions.
*/
+#ifndef SCHED_IMPLEMENTATION
+
static inline void
sched_userret(struct thread *td)
{
@@ -404,6 +427,8 @@ sched_userret(struct thread *td)
sched_userret_slowpath(td);
}
+#endif /* SCHED_IMPLEMENTATION */
+
static __inline void
sched_pin(void)
{
@@ -475,6 +500,7 @@ extern int dtrace_vtime_active;
extern dtrace_vtime_switch_func_t dtrace_vtime_switch_func;
#endif
+#if defined(SCHED_IMPLEMENTATION) || defined(SCHED_SHIM)
/*
* Scheduler instance structure.
*/
@@ -495,22 +521,26 @@ struct sched_selection {
};
#define _SCHED_DECLARE_FIELD_FUN(args, ret_type, fn, ...) \
- .SCHED_ITF_FIELD_NAME(fn) = &_SCHED_ITF_IMPL_FUNCTION_NAME( \
+ .SCHED_ITF_FIELD_NAME(fn) = &SCHED_ITF_IMPL_FUNCTION_NAME( \
_SCHED_ITF_ARG1 args, fn),
+#endif /* SCHED_IMPLEMENTATION || SCHED_SHIM */
-#define DECLARE_SCHEDULER(var_name, string_name) \
+#ifdef SCHED_IMPLEMENTATION
+#define DECLARE_SCHEDULER(string_name) \
static const struct sched_instance \
- __CONCAT(_sched_instance_, var_name) = { \
+ __CONCAT(_sched_instance_, SCHED_IMPLEMENTATION) = { \
SCHED_ITF_NOCOMMON(_SCHED_DECLARE_FIELD_FUN, \
- var_name) \
+ SCHED_IMPLEMENTATION) \
}; \
static const struct sched_selection \
- __CONCAT(_sched_selector_, var_name) = { \
+ __CONCAT(_sched_selector_, SCHED_IMPLEMENTATION) = { \
.name = string_name, \
- .instance = &__CONCAT(_sched_instance_, var_name), \
+ .instance = &__CONCAT(_sched_instance_, \
+ SCHED_IMPLEMENTATION), \
}; \
DATA_SET(sched_instance_set, \
- __CONCAT(_sched_selector_, var_name));
+ __CONCAT(_sched_selector_, SCHED_IMPLEMENTATION));
+#endif /* SCHED_IMPLEMENTATION */
void sched_instance_select(void);
diff --git a/sys/tools/sched_impl_ns.awk b/sys/tools/sched_impl_ns.awk
new file mode 100644
index 000000000000..7c515ac0ec4f
--- /dev/null
+++ b/sys/tools/sched_impl_ns.awk
@@ -0,0 +1,38 @@
+#!/usr/bin/awk -f
+
+# Copyright (c) 2026 The FreeBSD Foundation
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# This software was developed by Olivier Certner <olce.freebsd@certner.fr>
+# at Kumacom SARL under sponsorship from the FreeBSD Foundation.
+
+/^__END__$/ {
+ keep = 0;
+}
+
+keep != 0 && $1 == "__CHECK_IMPLEMENTATION__" {
+ # Check that SCHED_IMPLEMENTATION is defined
+ print "#if !defined(SCHED_IMPLEMENTATION)";
+ print "#error SCHED_IMPLEMENTATION not defined"
+ print "#endif"
+ # Check that it is consistent with that used to generate the header
+ printf("#define _SCHED_IMPL_CHECK_FAILED_%s\n", $2)
+ printf("/* Check that SCHED_IMPLEMENTATION is '%s'. */\n", $2);
+ print "__CONCAT(_SCHED_IMPL_CHECK_FAILED_, SCHED_IMPLEMENTATION)"
+ printf("#undef _SCHED_IMPL_CHECK_FAILED_%s\n", $2)
+ no_print = 1;
+}
+
+keep != 0 && no_print == 0 {
+ gsub("__NL__", "\n");
+ print;
+}
+
+{
+ no_print = 0;
+}
+
+/^__START__$/ {
+ keep = 1;
+}