July 14, 2007 CSF 9

### NAME

CSF - The NetBSD common scheduler framework

### SYNOPSIS

```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`)

### DESCRIPTION

CSF provides a modular and self-contained interface for implementing different thread scheduling algorithms. The different schedulers can be selected at compile-time. Currently, the only scheduler available is sched_4bsd(9), the traditional 4.4BSD thread scheduler.

The interface is divided into two parts: A set of functions each scheduler needs to implement and common functions used by all schedulers.

### Scheduler-specific functions

The following functions have to be implemented by the individual scheduler.

#### Scheduler initialization

```void`sched_cpuattach(```, struct cpu_info *`)
  Per-CPU scheduler initialization routine.

```void`sched_rqinit(```, void`)
  Initialize the scheduler's runqueue data structures.

```void`sched_setup(```, void`)
  Setup initial scheduling parameters and kick off timeout driven events.

#### Runqueue handling

Runqueue handling is completely internal to the scheduler. Other parts of the kernel should access runqueues only through the following functions:

```void`sched_enqueue(```, lwp_t *``, bool`)
  Place an LWP within the scheduler's runqueue structures.

```void`sched_dequeue(```, lwp_t *`)
  Remove an LWP from the scheduler's runqueue structures.

```lwp_t``*`sched_nextlwp(```, void`)
  Return the LWP that should run the CPU next.

```bool`sched_curcpu_runnable_p(```, void`)
  Indicate if there is a runnable LWP for the current CPU.

```void`sched_print_runqueue(```, void (*pr)(const char *, ...)`)
  Print runqueues in DDB.

#### Core scheduler functions

```void`sched_tick(```, struct cpu_info *`)
  Periodically called from hardclock(9). Determines if a reschedule is necessary, if the running LWP has used up its quantum.

```void`sched_schedclock(```, lwp_t *`)
  Periodically called from schedclock(``) in order to handle priority adjustment.

#### Priority adjustment

```void`sched_nice(```, struct proc *, int`)
  Recalculate the process priority according to its nice value.

#### General helper functions

```void`sched_proc_fork(```, struct proc *``, struct proc *`)
  Inherit the scheduling history of the parent process after fork(``).

```void`sched_proc_exit(```, struct proc *``, struct proc *`)
  Charge back a processes parent for its resource usage.

```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 for setrunnable(``).

```void`sched_pstats_hook(```, struct proc *``, int`)
  Scheduler-specific actions for sched_pstats(``).

### Common scheduler functions

```pri_t`sched_kpri(```, lwp_t *`)
  Scale a priority level to a kernel priority level, usually for an LWP that is about to sleep.

```void`sched_pstats(```, void *`)
  Update process statistics and check CPU resource allocation.

```inline` `void`resched_cpu(```, lwp_t *`)
  Arrange for a reschedule.

```void`setrunnable(```, lwp_t *`)
  Change process state to be runnable, placing it on a runqueue if it is in memory, awakening the swapper otherwise.

```void`schedclock(```, lwp_t *`)
  Scheduler clock. Periodically called from statclock(``).

```void`sched_init(```, void`)
  Initialize callout for sched_pstats(``) and call sched_setup(``) to initialize any other scheduler-specific data.

### CODE REFERENCES

This section describes places within the NetBSD source tree where actual code implementing the scheduler can be found. All pathnames are relative to ```/usr/src`.

The CSF programming interface is defined within the file ```sys/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`.

### SEE ALSO

mi_switch(9), preempt(9), sched_4bsd(9)

### HISTORY

The CSF appeared in NetBSD5.0.

### AUTHORS

The CSF was written by Daniel Sieger
<dsieger@NetBSD.org>.