MI_SWITCH(9)

πŸ“¦
version 15.1 Β· 3 versions
, in freebsd 14.5, freebsd 15.1, nixpkgs unstable

πŸ’– MI_SWITCH(9) πŸ’–

okay so bestie, welcome to MI_SWITCH(9) from the Kernel Developer's Manual β€” this is the page about mi_switch, aka the actual moment a thread hands over the CPU like a relay baton πŸŽ€. lowkey iconic, extremely load-bearing. let's get into it ✨


🌸 NAME 🌸

mi_switch β€” switch to another thread context πŸ’…

✨ SYNOPSIS ✨

#include <sys/param.h>
#include <sys/proc.h>

void
mi_switch(int flags);

πŸ¦‹ DESCRIPTION πŸ¦‹

So. The mi_switch() function implements the machine-independent prelude to a thread context switch. It's the single entry point for every context switch β€” literally the one door everybody walks through πŸšͺ✨ β€” and it gets called from only a few distinguished places in the kernel.

And here's the vibe: the context switch is, by necessity, always performed by the switched thread, even when the switch is initiated from elsewhere β€” like, say, preemption requested via Inter-Processor Interrupt (IPI). the thread does its own switching. main character energy, no cap πŸ‘‘

The various major uses of mi_switch() can be enumerated as follows:

  1. From within a function such as sleepq_wait(9) or turnstile_wait() when the current thread voluntarily relinquishes the CPU to wait for some resource or lock to become available. (it's giving "imma sit this one out" πŸ’€)
  2. Involuntary preemption due to arrival of a higher-priority thread. (rude but valid πŸ™ˆ)
  3. At the tail end of critical_exit(9), if preemption was deferred due to the critical section.
  4. Within the TDA_SCHED AST handler, when rescheduling before the return to usermode was requested. There are several reasons for this, a notable one coming from sched_clock() when the running thread has exceeded its time slice. ⏰
  5. In the signal handling code (see issignal(9)) if a signal is delivered that causes a process to stop.
  6. In thread_suspend_check() where a thread needs to stop execution due to the suspension state of the process as a whole.
  7. In kern_yield(9) when a thread wants to voluntarily relinquish the processor. (so polite 🫢)

The flags argument to mi_switch() indicates the context switch type. One of the following must be passed:

  • SWT_OWEPREEMPT β€” Switch due to delayed preemption after exiting a critical section.
  • SWT_TURNSTILE β€” Switch after propagating scheduling priority to the owner of a resource.
  • SWT_SLEEPQ β€” Begin waiting on a sleepqueue(9).
  • SWT_RELINQUISH β€” Yield call.
  • SWT_NEEDRESCHED β€” Rescheduling was requested.
  • SWT_IDLE β€” Switch from the idle thread.
  • SWT_IWAIT β€” A kernel thread which handles interrupts has finished work and must wait for interrupts to schedule additional work.
  • SWT_SUSPEND β€” Thread suspended.
  • SWT_REMOTEPREEMPT β€” Preemption by a higher-priority thread, initiated by a remote processor.
  • SWT_REMOTEWAKEIDLE β€” Idle thread preempted, initiated by a remote processor.
  • SWT_BIND β€” The running thread has been bound to another processor and must be switched out.

In addition to the switch type, callers must specify the nature of the switch by performing a bitwise OR with one of the SW_VOL or SW_INVOL flags, but not both β€” pick a lane bestie, not two 🫠. Respectively, these flags denote whether the context switch is voluntary or involuntary on the part of the current thread. For an involuntary context switch in which the running thread is being preempted, the caller should also pass the SW_PREEMPT flag.

okay important one πŸ‘‡ Upon entry to mi_switch(), the current thread must be holding its assigned thread lock. It may be unlocked as part of the context switch. After they have been rescheduled and execution resumes, threads will exit mi_switch() with their thread lock unlocked. don't forget this fr fr πŸ’€

mi_switch() records the amount of time the current thread has been running before handing control over to the scheduler, via sched_switch(). After selecting a new thread to run, the scheduler will call cpu_switch() to perform the low-level context switch. πŸŒ€

cpu_switch() is the machine-dependent function that performs the actual switch from the running thread oldtd to the chosen thread newtd. πŸ”₯


🌈 SEE ALSO 🌈

cpu_switch(9), cpu_throw(9), critical_exit(9), issignal(9), kern_yield(9), mutex(9), pmap(9), sleepqueue(9), thread_exit(9)


that's the whole page babes, go forth and switch contexts responsibly πŸ§šβ€β™€οΈπŸ’œ

Debian Β· January 7, 2025 Β· MI_SWITCH(9) β€” mwah, thanks for reading, ily, bye πŸ‘‹πŸ’–

πŸ“¦ where this page comes from