How Does Interrupt Handling Work in an OS?
Learn how interrupt handling works — vector dispatch, top-half/bottom-half split, and context restore — with OS interview questions.
Expected Interview Answer
Interrupt handling is the sequence by which the CPU detects an interrupt request, saves the currently running task’s state, looks up and runs a dedicated handler routine, and then restores the original state so execution resumes as if nothing happened.
When a device asserts its interrupt request line, the CPU finishes the current instruction, then checks whether interrupts are enabled and whether the requesting interrupt’s priority is high enough to be accepted; if so, it disables further interrupts of equal or lower priority, pushes the minimal context (program counter, flags, sometimes a few registers) onto the stack or into a dedicated save area, and jumps to the handler address found in the interrupt vector table using the interrupt number as an index. The handler — often split into a short, fast top half that acknowledges the device and does the minimum urgent work, and a deferred bottom half that does the heavier processing later — services the device, for example reading a byte from a UART or acknowledging a completed DMA transfer. Once done, the handler executes a return-from-interrupt instruction that restores the saved context and re-enables interrupts, resuming the interrupted code exactly where it left off. Getting this right requires care around re-entrancy, interrupt priority levels, and keeping handlers short so high-priority events are not delayed.
- Explains why handlers must be short and fast (top half / bottom half split)
- Shows how the vector table maps interrupt numbers to handler code
- Clarifies why interrupts are masked during handling to avoid re-entrancy bugs
- Grounds understanding of device drivers and real-time responsiveness
AI Mentor Explanation
Interrupt handling is like a twelfth man rushing onto the field the instant a fielder signals injury: play is paused at the exact ball boundary, the injury is noted, and a substitute steps in following a known checklist — check the injury, treat what is urgent, and either return the original fielder or bring on a full replacement later. Only urgent first aid happens on the field immediately; deeper treatment is deferred to the dressing room, just as a handler defers heavy work to a bottom half. Once done, play resumes exactly from where the over left off.
Step-by-Step Explanation
Step 1
Interrupt request asserted
A device raises its interrupt request line; the CPU finishes the current instruction before checking for pending interrupts.
Step 2
Priority check and masking
The CPU checks if interrupts are enabled and if this request outranks the current priority; if accepted, it masks equal/lower-priority interrupts.
Step 3
Context save and vector dispatch
Minimal context (PC, flags) is saved, and control jumps to the handler address found via the interrupt number in the vector table.
Step 4
Handle and return
The top-half handler services the device urgently, optionally schedules bottom-half work, then a return-from-interrupt instruction restores context and resumes the interrupted code.
What Interviewer Expects
- A clear step-by-step: assert, mask/priority-check, save context, vector dispatch, handle, restore
- Understanding of the interrupt vector table as the number-to-handler lookup
- Awareness of top-half/bottom-half (or equivalent deferred work) split
- Why handlers must be short to avoid blocking higher-priority interrupts
Common Mistakes
- Thinking the whole handler runs with interrupts still fully enabled by default
- Forgetting that the vector table maps interrupt numbers, not device names, to handlers
- Doing heavy, slow work directly inside the top-half handler
- Not knowing that execution resumes at the exact interrupted instruction, not from the start
Best Answer (HR Friendly)
“When a device needs attention, the CPU pauses what it is doing, remembers exactly where it was, and jumps to a small piece of code built specifically to handle that device. That handler does only the urgent part quickly, and once it is done, the CPU picks up exactly where it left off as if nothing happened. Well-designed systems keep that handler code very short so nothing else gets delayed.”
Code Example
/* Vector table maps IRQ number to handler function */
void (*isr_table[NUM_IRQS])(void);
void register_handler(int irq, void (*handler)(void)) {
isr_table[irq] = handler;
}
/* Top half: runs with interrupts masked, must be fast */
void uart_rx_isr(void) {
uint8_t byte = UART_DATA_REG; /* urgent: drain the hardware FIFO */
ring_buffer_push(&rx_queue, byte);
schedule_bottom_half(uart_process_rx); /* defer heavier parsing */
UART_ACK_IRQ(); /* tell the device we handled it */
}
/* CPU-level dispatch (conceptual) */
void interrupt_dispatch(int irq) {
save_context();
mask_lower_priority(irq);
isr_table[irq](); /* jump via vector table */
unmask_all();
restore_context(); /* resumes exact interrupted point */
}Follow-up Questions
- Why is it dangerous to do heavy processing inside a top-half interrupt handler?
- How does interrupt priority masking prevent a low-priority handler from blocking a critical one?
- What is the difference between edge-triggered and level-triggered interrupts?
- How does a bottom half or deferred procedure call get scheduled after the top half returns?
MCQ Practice
1. What is saved before an interrupt handler runs?
The CPU saves just enough state — program counter, flags, and sometimes a few registers — to resume execution afterward.
2. Why is interrupt handling code typically split into a top half and bottom half?
Keeping the top half short minimizes the time interrupts stay masked, so higher-priority events are not delayed by slow processing.
3. What does the interrupt vector table provide?
The vector table is indexed by interrupt number and holds the address of the corresponding handler routine.
Flash Cards
What is interrupt handling? — The process of saving state, dispatching to a handler via the vector table, servicing the device, and resuming.
Why split into top half and bottom half? — To keep the interrupts-masked portion fast and defer heavier processing.
What resumes after the handler returns? — The exact interrupted instruction, via a return-from-interrupt instruction.
What indexes the interrupt vector table? — The interrupt number.