Context Switching
Context switching in CPU happens in two different ways.
- OS scheduling different threads as part of preemptive scheduling.
- The CPU itself switches context due to hardware interrupts, software interrupts, and exceptions.
Context Switch by OS - Software Switch
When the OS switches context, it saves the current CPU context. It uses a structure called the Process Control Block. This sits in the process's memory, set up when the process is created.
The OS uses this structure to store the current state of the MMU, the CPU registers, and more.
The data needed to reschedule the thread is copied to the PCB.
When the OS reschedules a thread, it copies all the data back from the PCB. The CPU can continue where it left off.
Process with multiple threads
When a process has many threads, the OS keeps one structure per thread. It's called the Thread Control Block (TCB). One PCB holds a list of TCB objects for all the process's threads.
When a thread is scheduled, the OS uses its TCB to store and restore its context.
Context Switch by CPU - Hardware Switch
Say the CPU is running instructions. An interrupt signal arrives, from a device or a system call. The CPU then saves the current run to a part of the process's memory. This is the kernel stack.
Each CPU has one kernel interrupt stack.
The CPU first stores the current context on this stack. Then it runs the interrupt handler. When the handler returns, the saved context is at the bottom of the stack. The CPU uses it to restore and continue.
This stack stores the current CPU registers, flag registers, and more.
The interrupt handler runs on top of this stack. When it returns, it restores the saved values from the interrupted process. Then it runs the IRET/sysret instruction.
If a new interrupt arrives during an interrupt, that run is also paused. It's saved to the same interrupt stack.
Kernel Stack and User Stack
Every thread in Linux has a kernel stack and a user stack. On a system call, the CPU switches to kernel mode. The system call handler then sets the CPU registers to use the kernel stack. It runs all system calls and exceptions there, such as page faults.
Each CPU has one interrupt stack. It's used only for hardware interrupts.
The kernel stack is one per thread. It's used by system calls and exceptions.