Introduction
A context switch is the mechanism by which the OS saves the state of a currently running process and restores the state of another process so it can resume execution. Context switches happen whenever the scheduler decides to give the CPU to a different process — due to an interrupt, a system call that blocks, or the expiration of a time slice.
Cricket analogy: A context switch is like the twelfth man running on to swap gear with a fielder who's about to bowl a different over, saving the exact field position and pace so the original bowler can resume seamlessly later when their over comes back around.
Explanation
During a context switch, the kernel saves the current process's execution context into its PCB: the program counter, all general-purpose CPU registers, the stack pointer, and processor status flags. It may also need to save memory-management state such as page table base registers (on many architectures, this is captured via updating the CR3 register on x86 or similar TLB-related state). The kernel then loads the saved context of the next process to run from its PCB, restoring its registers, program counter, and memory mappings, and control transfers to that process at exactly the point where it previously left off. Crucially, a context switch performs no useful computation for either process — every cycle spent saving and restoring state is pure overhead. This is why operating systems try to minimize context switch frequency and cost: modern kernels use techniques like lightweight context representations, hardware support for fast register saves, and avoiding unnecessary TLB flushes to reduce this overhead. The cost of a context switch also depends on hardware architecture (number of registers, availability of specialized instructions) and system load (cache and TLB state must effectively be 'reloaded' as the new process runs, causing indirect performance costs beyond the switch itself).
Cricket analogy: Saving the PCB is like a scorer meticulously recording the exact ball, over, field placements, and score before handing the book to a relief scorer, and every second spent on that handover adds no runs to the board - pure overhead the match tries to minimize between overs.
Example
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>
/* Rough illustration: repeatedly yielding forces context switches
between parent and child, whose cumulative cost can be measured. */
int main(void) {
struct timespec start, end;
pid_t pid = fork();
if (pid == 0) {
for (int i = 0; i < 100000; i++) {
sched_yield(); /* voluntarily give up the CPU: forces a switch */
}
_exit(0);
} else {
clock_gettime(CLOCK_MONOTONIC, &start);
for (int i = 0; i < 100000; i++) {
sched_yield();
}
wait(NULL);
clock_gettime(CLOCK_MONOTONIC, &end);
double elapsed = (end.tv_sec - start.tv_sec) +
(end.tv_nsec - start.tv_nsec) / 1e9;
printf("Elapsed time for ~200000 yields (context switches): %.4f s\n",
elapsed);
}
return 0;
}Analysis
Each call to sched_yield() asks the kernel to move the calling process out of Running and let the scheduler pick another ready process, forcing a context switch between the parent and child. If you measure this program's total time and divide by the number of yields, you get a rough per-switch cost estimate. That entire elapsed time represents work the CPU did that advanced neither process's actual computation (like sum totals or I/O) — it was spent purely saving one process's registers and restoring another's, plus the indirect cost of cold caches and TLB entries after the switch.
Cricket analogy: Calling sched_yield() repeatedly is like a bowler voluntarily handing the ball to the other end every single delivery just to measure handover time, and timing the total handovers divided by count gives a rough per-handover cost - time that scored no runs for either bowler.
Key Takeaways
- A context switch saves the current process's registers and program counter into its PCB, then restores another process's saved state.
- Context switches are triggered by interrupts, blocking system calls, and time-slice expiry.
- A context switch does zero useful work for any process — it is pure overhead.
- Indirect costs include cold CPU caches and TLB entries after switching to a different process's memory context.
- Minimizing unnecessary context switches is a key performance goal for OS and scheduler design.
Practice what you learned
1. What is saved and restored during a context switch?
2. Why is a context switch considered 'pure overhead'?
3. Which of these is a common trigger for a context switch?
4. What indirect cost, beyond register save/restore, does a context switch often introduce?
Was this page helpful?
You May Also Like
Process States and the PCB
Understand the five standard process states and the fields stored in a Process Control Block.
Introduction to Process Scheduling
Learn why the OS schedules processes, the queues involved, and the basic goals of a scheduler.
Threads and Multithreading
Learn how threads differ from processes, why multithreading helps, and user-level vs kernel-level threads.