Introduction
This post is more focused on the architecture of computer systems and how they handle events rather than the operating system itself. It is a continuation of our previous posts on operating systems, where we discussed processes, system calls, and the role of the OS in managing resources. This is more lower-level than the previous posts, but it is still relevant to understanding how operating systems work.
In our previous posts, we’ve explored how the operating system manages processes and how applications request services through system calls. But there’s another critical aspect of operating systems we haven’t covered yet: how does your OS respond to external events that happen at unpredictable times?
When you press a key, click your mouse, or receive a network packet, your computer can’t predict exactly when these events will occur. Yet it responds to them almost instantly. This responsiveness is made possible by interrupts — mechanisms that allow hardware devices to signal the CPU and temporarily pause whatever it’s doing to handle urgent events.
Table of Contents
- What Exactly Is an Interrupt?
- The Three Types of Interrupts
- The Anatomy of an Interrupt
- Interrupt Priority and Masking
- The Unsung Hero: Timer Interrupts
- Interrupt Handlers: Designed for Speed
- Coming Up Next
What Exactly Is an Interrupt?
An interrupt is essentially an electronic signal sent to the CPU that causes it to pause its current execution, save its state, and jump to a special piece of code called an interrupt handler that deals with the event that triggered the interrupt. Once the handler finishes, the CPU returns to whatever it was doing before.
Think of interrupts like a doorbell. You might be in the middle of cooking dinner when the doorbell rings. You save your place in the recipe, answer the door, deal with the visitor, and then return to cooking exactly where you left off.
The Three Types of Interrupts
Not all interrupts are created equal. They come in several varieties, each serving different purposes:
Hardware Interrupts
These originate from physical devices connected to your computer:
- Keyboard interrupts: When you press or release a key
- Mouse interrupts: When you move or click your mouse
- Disk controller interrupts: When a read/write operation completes
- Network card interrupts: When a packet arrives
- Timer interrupts: When a predefined time interval elapses
- Power management interrupts: When battery status changes or power buttons are pressed
Software Interrupts (Traps)
These are generated by software when it needs kernel assistance:
- System calls: As we discussed in our previous post, applications trigger these to request OS services
- Exceptions: Like division by zero or accessing invalid memory
- Breakpoints: Used by debuggers to pause program execution
Inter-processor Interrupts (IPIs)
These occur in multi-processor systems when one CPU core needs to signal another:
- Cache coherency notifications: To maintain memory consistency across cores
- Scheduling requests: When the OS wants to balance load across cores
- TLB shootdowns: When page tables change and cached address translations need to be invalidated
The Anatomy of an Interrupt
Let’s break down what happens when an interrupt occurs:
- Detection: A device triggers an interrupt signal on the system bus
- Acknowledgment: The CPU acknowledges the interrupt
- State saving: The current program’s state (program counter, registers, etc.) is saved
- Handler location: The CPU uses the interrupt number to find the appropriate handler address in the interrupt vector table
- Handler execution: The CPU jumps to the handler code, which runs in kernel mode
- Device servicing: The handler communicates with the device and processes the event
- State restoration: The original program’s state is restored
- Resumption: The interrupted program continues executing
This process is often referred to as “context switching,” and it’s a fundamental part of how modern operating systems achieve multitasking. This entire process happens so quickly that you never notice the interruption.
Interrupt Priority and Masking
Not all interrupts are equally important. A timer interrupt ensuring fair CPU sharing might be less urgent than a power failure notification. To handle this, CPUs implement:
- Interrupt priority levels: Determining which interrupts can interrupt others
- Interrupt masking: Temporarily disabling specific types of interrupts
- Critical sections: Code sequences during which interrupts may be disabled
These mechanisms ensure that the most critical interrupts get serviced first while preventing less important interrupts from causing chaos in sensitive operations.
The Unsung Hero: Timer Interrupts
Of all the interrupt types, one deserves special attention: the timer interrupt. Timer interrupts occur at regular intervals (typically hundreds or thousands of times per second) and serve several critical functions:
- Enabling preemptive multitasking: They allow the OS to regain control from running processes, essential for the time-sharing we discussed in earlier posts
- Maintaining system time: They help track the passage of time
- Monitoring timeouts: They help detect when operations take too long
- Scheduling periodic tasks: Many system housekeeping activities happen on timer interrupts
Without timer interrupts, a misbehaving program could monopolize the CPU indefinitely. They’re the heartbeat of your operating system, ensuring regular opportunities to make scheduling decisions.
Interrupt Handlers: Designed for Speed
Interrupt handlers are special pieces of code with unique characteristics:
- They run in kernel mode: With full privileges
- They must be fast: Long-running handlers delay other interrupts and the system’s return to normal operation
- They cannot block: They can’t wait for resources or sleep
- They have limited context: They can’t assume which process was running when they were triggered
To accommodate these constraints, modern operating systems often split interrupt handling into two parts:
- Top half (Immediate handler): Runs in interrupt context, acknowledges the interrupt, gets essential data, and queues the rest of the work
- Bottom half (Deferred handler): Runs later in a more permissive context, performing the bulk of the processing
This division helps keep the system responsive while allowing for complex interrupt processing.
Coming Up Next
Now that we understand how the outside world gets the kernel’s attention through interrupts, our next post will examine what happens when the CPU switches between different processes. We’ll dive into the fascinating world of Context Switching and explore the hidden costs of multitasking that impact your system’s performance.