Interrupts and Timers
Imagine you are reading a book. Suddenly the doorbell rings. You stop reading, put a bookmark in, answer the door, and then come back and pick up where you left off. That is exactly how a hardware interrupt works.
What Is an Interrupt?
An interrupt is a signal from a piece of hardware saying "pay attention to me!" When the CPU receives an interrupt, it pauses whatever it was doing, handles the event, and then goes back to its previous work.
Without interrupts, the CPU would have to keep checking every device over and over: "Keyboard, did you get a key press? Disk, are you done reading? Timer, is it time yet?" This wasteful checking is called polling, and it is like constantly peeking out the window to see if anyone is at the door.
With interrupts, the devices ring the doorbell only when something actually happens. The CPU can focus on useful work the rest of the time.
The Interrupt Controller
In a real computer, a chip called the interrupt controller sits between the devices and the CPU. It has a list of interrupt vectors -- numbered slots, one for each kind of event.
| Vector | Device | Priority |
|---|---|---|
| 0 | Timer | High |
| 16 | I/O completion | Normal |
When a device needs attention, it sends a signal to the controller. The controller adds the request to a queue. When the CPU is ready, it asks the controller "what needs handling?" and the controller serves requests in priority order -- urgent ones first.
In PyOS, the InterruptController class does exactly this:
Interrupt Masking
Sometimes the OS needs to do something without being interrupted -- like updating a shared data structure. It can mask (silence) certain vectors temporarily. Masked interrupts still get queued, but they are not delivered until the vector is unmasked.
Think of it like putting your phone on silent. Calls still come in (you see them later), but your phone does not ring while you are concentrating.
interrupt mask 0 # Silence the timer
tick 5 # Ticks happen, but timer interrupts queue silently
interrupt unmask 0 # Resume -- queued interrupts are delivered
The Timer
The timer is a special device that ticks at a regular rate. Every N ticks, it fires an interrupt. The OS uses this for three things:
- Preemption -- giving each process a fair time slice, then switching to the next one.
- Timekeeping -- tracking how long things take.
- Timeouts -- knowing when to retry a network request.
In PyOS, the timer is a TimerDevice that plugs into the interrupt controller. You can check its status and change how often it fires:
timer info
Timer device:
Interval: 5 ticks
Current tick: 0
Total ticks: 0
Total fires: 0
timer set 3 # Fire every 3 ticks instead of 5
Ticking the System Clock
In a real computer, the timer ticks automatically based on a crystal oscillator. In PyOS, we advance time manually with the tick command:
Each tick:
- Advances the timer counter by one.
- If the counter reaches the interval, the timer fires -- it sends an interrupt to the controller.
- The controller delivers all pending interrupts to their handlers.
- The timer handler checks if the current process has used up its time slice. If so, it preempts the process -- moving it from RUNNING back to the ready queue -- so the next dispatch runs a different process.
tick()reports this by returningpreempted: True.
Timer-Driven Preemption
Without a timer, a process could hog the CPU forever. The timer makes preemptive scheduling possible:
- The scheduler gives a process a quantum (a fixed number of ticks to run).
- The timer counts ticks.
- When ticks reach the quantum, the timer fires and the kernel preempts the running process, moving it to the back of the ready queue so the next dispatch runs someone else.
This is how Round Robin, MLFQ, and CFS schedulers ensure fairness -- no single process can monopolise the CPU. Non-preemptive policies (FCFS and Priority) have no quantum, so the timer never preempts them.
How Interrupts Fit in the Big Picture
┌─────────────────────────────────────────────────┐
│ Kernel │
│ │
│ Timer ──fire──▶ Interrupt ──dispatch──▶ │
│ Device Controller Handler │
│ │
│ Disk ──done──▶ (queue by ──dispatch──▶ │
│ NIC priority) Handler │
│ │
└─────────────────────────────────────────────────┘
Devices raise interrupts. The controller queues them by priority. Handlers process them. The kernel keeps running.
Try It Yourself
Boot PyOS and run the interactive lesson:
Or experiment manually:
timer info # See the timer's state
tick 5 # Advance 5 ticks (timer fires once at default interval)
interrupt list # See all registered vectors
interrupt mask 0 # Silence the timer
tick 5 # Timer queues but doesn't fire
interrupt unmask 0 # Resume delivery
tick 1 # Queued interrupt is now serviced
Where to Go Next
- TCP: Reliable Delivery -- How TCP guarantees data arrives complete and in order
- Devices and Networking -- Hardware devices and network fundamentals
- Processes -- How preemption uses timer interrupts to switch processes
Key Terms
| Term | Definition |
|---|---|
| Interrupt | A signal from hardware or software that tells the CPU to stop and handle something |
| IRQ | Interrupt Request -- the actual signal sent to the interrupt controller |
| Vector | A number that identifies which device or event is interrupting |
| Handler | A function the OS runs when a specific interrupt fires |
| Masking | Temporarily disabling an interrupt so it is queued but not delivered |
| Timer | A hardware clock that fires an interrupt at regular intervals (ticks) |
| Preemption | Using timer interrupts to forcibly switch the running process, giving everyone a fair turn |
| Tick | One unit of time in the system timer -- the heartbeat of the OS |