CSF(9)
π CSF(9) β the NetBSD common scheduler framework π
okay so welcome to the Kernel Developer's Manual, section 9 (that (9) is the kernel-dev section, iykyk), and today's main character is CSF β the NetBSD common scheduler framework. it's giving "the friend who organizes the group chat so everyone actually shows up on time" but for threads. π§β¨
β¨ SYNOPSIS β¨
like all good kernel things, it starts with an include. copy these exactly, bestie, no freestyling:
#include <sys/sched.h>
void
sched_rqinit(void);
void
sched_setup(void);
void
sched_cpuattach(struct cpu_info *);
void
sched_tick(struct cpu_info *);
void
sched_schedclock(lwp_t *);
bool
sched_curcpu_runnable_p(void);
lwp_t *
sched_nextlwp(void);
void
sched_enqueue(lwp_t *, bool);
void
sched_dequeue(lwp_t *);
void
sched_nice(struct proc *, int);
void
sched_proc_fork(struct proc *, struct proc *);
void
sched_proc_exit(struct proc *, struct proc *);
void
sched_lwp_fork(lwp_t *);
void
sched_lwp_exit(lwp_t *);
void
sched_setrunnable(lwp_t *);
void
sched_print_runqueue(void (*pr)(const char *, ...));
void
sched_pstats_hook(struct proc *, int);
void
sched_pstats(void *arg);
pri_t
sched_kpri(lwp_t *);
void
resched_cpu(lwp_t *);
void
setrunnable();
void
schedclock(lwp_t *);
void
sched_init(void);
that's a lot of prototypes but honestly? iconic. π
π DESCRIPTION π
okay so CSF provides a modular and self-contained interface for implementing different thread scheduling algorithms. the different schedulers can be selected at compile-time β so you pick your fave before the build, not at runtime, no cap.
currently the schedulers available are:
sched_4bsd(9)β the traditional 4.4BSD thread scheduler, the OG π«Άsched_m2(9)β which implements a SVR4/Solaris like approach β¨
the interface is split into two parts:
- a set of functions each scheduler needs to implement
- common functions used by all schedulers
πΈ SCHEDULER-SPECIFIC FUNCTIONS πΈ
the following functions have to be implemented by the individual scheduler. like, mandatory. no skipping. π
π Scheduler initialization
void sched_cpuattach(struct cpu_info *)β per-CPU scheduler initialization routine. it's giving "getting each CPU dressed and ready for the day". πvoid sched_rqinit(void)β initialize the scheduler's runqueue data structures. the runqueues need a glow-up before they can hold anything, bestie.void sched_setup(void)β setup initial scheduling parameters and kick off timeout driven events. literally the "let's get this party started" function. π
π¦ Runqueue handling
runqueue handling is completely internal to the scheduler, so other parts of the kernel should access runqueues only through the following functions. like, respect the boundaries pls:
void sched_enqueue(lwp_t *, bool)β place an LWP within the scheduler's runqueue structures. get in, bestie, you're in the queue now. π«Άvoid sched_dequeue(lwp_t *)β remove an LWP from the scheduler's runqueue structures. bye bestie, you're out. πlwp_t * sched_nextlwp(void)β return the LWP that should run the CPU next. the way this function picks the next one up? main character selection energy fr fr. πbool sched_curcpu_runnable_p(void)β indicate if there is a runnable LWP for the current CPU. just a little vibe check. βvoid sched_print_runqueue(void (*pr)(const char *, ...))β print runqueues in DDB. debugging time, and the printer function is passed in aspr. π
β Core scheduler functions
void sched_tick(struct cpu_info *)β periodically called fromhardclock(9). it determines if a reschedule is necessary, if the running LWP has used up its quantum. like a "you've had your turn, share the aux" moment. πvoid sched_schedclock(lwp_t *)β periodically called fromschedclock()in order to handle priority adjustment. β¨
π Priority adjustment
void sched_nice(struct proc *, int)β recalculate the process priority according to its nice value. it's giving "be nice or be recalculated", and honestly both are valid. π
π General helper functions
void sched_proc_fork(struct proc *, struct proc *)β inherit the scheduling history of the parent process afterfork(). generational wealth but make it scheduling data. πvoid sched_proc_exit(struct proc *, struct proc *)β charge back a processes parent for its resource usage. yes, the parent gets the bill. that's just how it is. πΈvoid sched_lwp_fork(lwp_t *)β LWP-specific version of the above.void sched_lwp_exit(lwp_t *)β LWP-specific version of the above.void sched_setrunnable(lwp_t *)β scheduler-specific actions forsetrunnable(). π§void sched_pstats_hook(struct proc *, int)β scheduler-specific actions forsched_pstats(). β
π COMMON SCHEDULER FUNCTIONS π
these are the shared ones, the communal wardrobe of the scheduler world:
pri_t sched_kpri(lwp_t *)β scale a priority level to a kernel priority level, usually for an LWP that is about to sleep. sleepy time conversion service. π΄void sched_pstats(void *)β update process statistics and check CPU resource allocation. the "how are we all doing, is everyone okay" function. πinline void resched_cpu(lwp_t *)β arrange for a reschedule. simple, effective, slay. πvoid setrunnable(lwp_t *)β change process state to be runnable, placing it on a runqueue if it is in memory, awakening the swapper otherwise. two paths, one function, both valid. π¦void schedclock(lwp_t *)β scheduler clock. periodically called fromstatclock(). ticking away like a little timekeeper fairy. β°void sched_init(void)β initialize callout forsched_pstats()and callsched_setup()to initialize any other scheduler-specific data. the opening ceremony, basically. π
no cap:sched_curcpu_runnable_p()andsched_nextlwp()are in the runqueue-handling club, so if you're poking at runqueues directly from outside the scheduler you're doing it wrong. other parts of the kernel go through the functions above, periodt. β
π₯ CODE REFERENCES π₯
where to find all this in the source, for when you need to go read it yourself (and you will, bestie):
- the
CSFprogramming interface is defined within the filesys/sys/sched.h - functions common to all scheduler implementations are in
sys/kern/kern_synch.c - the traditional 4.4BSD scheduler is implemented in
sys/kern/sched_4bsd.c - the M2 scheduler is implemented in
sys/kern/sched_m2.c
π SEE ALSO π
go read these next, they're all part of the same lore:
π¦ HISTORY π¦
the CSF appeared in NetBSD 5.0. a whole era. π
π AUTHORS π
the CSF was written by Daniel Sieger β¨dsieger@NetBSD.orgβ©. give them their flowers, fr fr. π
and that's the page, bestie!! π«Ά this one came from the Debian source line, dated October 27, 2014, and it's CSF(9) in the Kernel Developer's Manual β go forth and schedule responsibly β¨π
π
π¦ where this page comes from
- nixpkgs unstable: netbsd-source 11.0
- Copyright (c) 2002 The NetBSD Foundation, Inc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms