[4.1.4] Interrupts & ISR
Interrupts and Interrupt Service Routines (ISRs)
Why computers need a way to react immediately
Computers are very fast, but they still need a way to pause what they are doing and respond to something urgent. An unexpected key press, an incoming network packet, a timer ticking, or a printer reporting that paper has run out are all events that may need attention now rather than later. An interrupt is a signal that tells the CPU to pause the current sequence of instructions and run special code to deal with the event. That special code is called an Interrupt Service Routine (ISR), sometimes called an interrupt handler.
Without interrupts, the CPU would have to keep checking devices in a loop, a method known as polling. Polling can waste time and energy and can also miss events that happen between checks. With interrupts, the device or the system itself generates a signal that causes the CPU to switch context and run the right ISR immediately. When the ISR finishes, control returns to the interrupted program as if nothing happened, apart from any changes that the ISR made to data or hardware state.
Core ideas in simple terms
Key definitions
- Interrupt: an asynchronous signal that requests immediate attention from the CPU.
- Interrupt Service Routine (ISR): a short, efficient routine that handles an interrupt.
- Interrupt vector: a number or address used to locate the correct ISR in a table, often shown in hexadecimal such as
0x20or0x80. - Interrupt vector table: a table that maps interrupt numbers to ISR starting addresses.
- Context: the current state of the CPU, such as register contents, the program counter and status flags, which must be saved before running the ISR and restored afterwards.
- Masking: temporarily disabling some interrupts so they cannot interrupt the current ISR or code section.
- Priority: a scheme that decides which interrupt is handled first if more than one occurs at the same time.
Why interrupts are important
- Responsiveness: the system can respond quickly to external events without constant checking.
- Efficiency: the CPU can do other work and only handle devices when required.
- Accuracy: time sensitive events such as timers and communication signals are serviced in time.
- Power saving: mobile devices can sleep until an interrupt wakes the CPU.
Types of interrupts with realistic scenarios
There are several ways an interrupt can be generated. Use the tabs to compare common cases and what triggers them.
Hardware interrupt: A keyboard controller or a network interface raises a signal when data is ready. Example: you press a key. The keyboard hardware generates an interrupt with a vector such as 0x21. The CPU pauses the current task, saves context and jumps to the keyboard ISR, which reads the keycode into a buffer and acknowledges the device. The ISR then returns so the user programme continues running.
Timer interrupt: A hardware timer generates regular interrupts at a fixed rate, for example 100 or 1000 times per second. The OS scheduler uses the timer ISR to keep time, wake sleeping processes and share the CPU fairly. Without periodic timer interrupts, pre-emptive multitasking would not work reliably.
Software interrupt: Application code requests an OS service, such as opening a file or sending a message, by executing a special instruction that triggers a controlled interrupt. On some systems this uses a fixed vector such as 0x80. The resulting ISR is part of the OS and validates the request, checks permissions and calls the relevant kernel routine.
How an interrupt is handled step by step
The general handling sequence
- Event occurs: a device, timer or software instruction asserts an interrupt line or code.
- CPU detects interrupt: if interrupts are enabled, the CPU completes the current instruction and begins the interrupt sequence.
- Context save: the CPU saves key parts of the current context, such as the program counter and status flags, usually on a stack.
- Vector lookup: the CPU uses the interrupt vector to find the start address of the correct ISR in the interrupt vector table.
- ISR runs: the handler performs the minimum useful work, such as reading data, clearing a device flag and placing data in a queue for later processing by a normal process.
- End of interrupt: the ISR acknowledges the device or controller and restores the saved context.
- Return to prior task: the CPU resumes the interrupted programme at the next instruction, or possibly switches to a different task if the scheduler decides so.
Design rules for ISRs
- Make ISRs short: do the least work needed to make the system safe and responsive, then hand off longer work to normal threads or processes.
- Protect shared data: if the ISR and normal code share variables or buffers, take care with critical sections to avoid race conditions.
- Acknowledge the source: clear device flags so the interrupt does not re-trigger immediately.
- Avoid blocking: do not wait for user input or long operations inside an ISR.
Priorities, masking and nested interrupts
Most systems support multiple interrupts at once. The CPU and interrupt controller use priority levels to decide which one to handle first. Software may also mask (temporarily disable) certain interrupts while a critical operation is in progress. The following tabs compare common scenarios.
The system is running a user programme when a disk device raises an interrupt. The CPU saves context and runs the disk ISR. While the ISR runs, all other interrupts are blocked. When the ISR finishes it restores context and returns to the user programme. This is simple, but a long ISR increases latency for other events.
The keyboard and the network interface raise interrupts close together. The network interrupt has higher priority because incoming packets can be time sensitive. The interrupt controller causes the CPU to run the network ISR first. The keyboard interrupt remains pending and is then serviced. This ordering reduces the chance of packet loss.
During a very short critical section that updates a shared data structure, software masks lower priority interrupts. If a masked interrupt occurs, it is queued by the controller and will be delivered as soon as masking is removed. Masking must be brief to avoid long delays that could lead to missed deadlines.
Comparing approaches: interrupts vs polling
| Aspect | Interrupt driven | Polling |
|---|---|---|
| CPU time | Used only when events occur | Spent repeatedly checking devices even when idle |
| Responsiveness | Usually very responsive with low latency | Can be delayed until next poll |
| Complexity | Requires ISRs, priorities and careful sharing of data | Simpler code but less efficient |
| Power | Allows sleep modes until interrupt | Prevents deep sleep if polling is constant |
Where the ISR lives and how it is found
The interrupt vector table
At boot, the operating system and hardware agree on the location of the interrupt vector table, which holds pointers to ISRs. Each entry corresponds to a particular interrupt number. For example, a keyboard interrupt might map to vector 0x21, and a timer tick might map to 0x20. When the interrupt occurs, the CPU multiplies the vector index by the size of an entry to fetch the address of the ISR and jumps there.
Saving and restoring context
To resume the interrupted programme correctly, the CPU must save the context before the ISR runs. Typically the return address and status flags are pushed onto a stack. The ISR may also save general purpose registers that it intends to use. Before returning, the ISR restores registers and flags so the previous code continues as if uninterrupted.
Edge cases and how systems cope
Interrupt handling must be robust. The tabs below show challenging situations and common strategies used to manage them.
A faulty device or driver can trigger repeated interrupts so quickly that normal work cannot proceed. Operating systems detect this and may throttle the source, switch the device to a slower mode, or temporarily disable the driver until the fault is cleared.
If ISRs run for too long or masking is used for extended periods, other interrupts can be delayed. Designers keep ISRs short and hand off longer tasks to background processes to reduce latency. Priority schemes ensure that time critical interrupts pre-empt less important ones.
ISRs may need to update shared buffers. If a normal process reads the same buffer, the system must avoid inconsistent states. Solutions include brief masking, lock-free ring buffers, or using variables that can be updated atomically by the hardware.
Deep Dive: interrupts and the scheduler
In a pre-emptive operating system, the timer ISR is the heartbeat of process scheduling. At each tick, the ISR updates time, checks which processes are ready to run and may request a context switch. The actual context switch often completes after the ISR returns, so that interrupt handling remains short. When a device ISR places data in a queue, the scheduler can wake a process that was waiting for that data. In this way interrupts connect the outside world to application code safely and efficiently.
Summary of key terminology
- Interrupt: a signal that requests immediate attention from the CPU.
- ISR: a short routine that handles an interrupt and prepares work for later processing.
- Interrupt vector: the numeric code used to index the vector table, for example
0x20. - Vector table: a table in memory containing addresses of ISRs.
- Masking: temporarily disabling selected interrupts.
- Priority: a ranking that determines which interrupt is serviced first.
- Polling: repeatedly checking a device without using interrupts.
Key Takeaways
- An interrupt lets the CPU react quickly to urgent events without constant polling.
- An ISR is a short, efficient routine that reads device data, clears flags and schedules any further work.
- Priorities and masking control which interrupts run first and which are delayed.
- The vector table maps interrupt numbers to the correct ISR address, for example
0x20or0x21. - Keeping ISRs short and safe reduces latency, avoids missed events and improves system stability.