---
name: "mi_switch"
section: "9"
platform: "freebsd"
package: "base"
version: "16.0-CURRENT-20261027-61c70dc16a79"
release: "FreeBSD 16.0-CURRENT (2026-10-27)"
platforms: ["linux", "freebsd"]
url: "https://new.carta.tech/mi_switch"
---

# mi\_switch(9)

switch to another thread context

## NAME

**mi\_switch** – switch to another thread context

## SYNOPSIS

**#include \<sys/param.h\>**

**#include \<sys/proc.h\>**

*void*\

**mi\_switch**(*int flags*);

## DESCRIPTION

The **mi\_switch**() function implements the machine-independent prelude to a thread context switch. It is the single entry point for every context switch and is called from only a few distinguished places in the kernel. The context switch is, by necessity, always performed by the switched thread, even when the switch is initiated from elsewhere; e.g. preemption requested via Inter-Processor Interrupt (IPI).

The various major uses of **mi\_switch**() can be enumerated as follows:

1. From within a function such as [sleepq\_wait(9)](/sleepq_wait/9.md) or **turnstile\_wait**() when the current thread voluntarily relinquishes the CPU to wait for some resource or lock to become available.

2. Involuntary preemption due to arrival of a higher-priority thread.

3. At the tail end of [critical\_exit(9)](/critical_exit/9.md), 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)](/issignal/9.md)) 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)](/kern_yield/9.md) when a thread wants to voluntarily relinquish the processor.

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)](/sleepqueue/9.md).

- 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. 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.

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.

**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_switch/9.md), [cpu\_throw(9)](/cpu_throw/9.md), [critical\_exit(9)](/critical_exit/9.md), [issignal(9)](/issignal/9.md), [kern\_yield(9)](/kern_yield/9.md), [mutex(9)](/mutex/9.md), [pmap(9)](/pmap/9.md), [sleepqueue(9)](/sleepqueue/9.md), [thread\_exit(9)](/thread_exit/9.md)
