Facebook Pixel

Mutual Exclusion Using Interrupt Disabling

When multiple processes are running and sharing data, the operating system has to make sure they do not collide inside a critical section. There are several ways to achieve this. Disabling interrupts is one of the oldest and most straightforward approaches, though it comes with enough drawbacks that modern systems rarely rely on it beyond a few very specific situations.

The Basic Idea

To understand why disabling interrupts works for mutual exclusion, you need to understand what interrupts actually do. An interrupt is a signal that tells the CPU to stop what it is currently doing and deal with something else. These signals come from hardware devices, timers, keyboards, disks, and sometimes software. Every time an interrupt fires, the CPU potentially switches from one process to another.

There are two categories of events that can cause a process switch:

  • Internal Events: Things the running process does itself, like voluntarily giving up the CPU or making a system call. These can be controlled through careful coding.
  • External Events: Things coming from outside, like a timer interrupt or a hardware signal. The only reliable way to stop these is to disable interrupts entirely.

So the logic is simple. If you disable interrupts before entering a critical section, the CPU cannot switch to another process. No timer, no keyboard, no disk signal gets through. The current process runs uninterrupted until it finishes with the shared data and re-enables interrupts on the way out.

The Steps

text
1. Process wants to enter the critical section
2. It disables all interrupts          -> disable_interrupts()
3. It enters the critical section
4. It updates shared data safely       -> No context switch possible
5. It exits the critical section
6. It re-enables interrupts            -> enable_interrupts()

In pseudocode, the pattern looks like this:

cpp
void process() {
    disable_interrupts();   // Block ALL external signals

    // --- Critical Section ---
    // Access shared data safely
    // No other process can run on this CPU

    enable_interrupts();    // Resume normal operation
}

Why It Works on a Single CPU

On a uniprocessor system, this approach genuinely guarantees mutual exclusion. The CPU runs one process at a time, and process switches depend almost entirely on interrupts. Block the interrupts, and you block the switches. No other process can sneak into the critical section because the CPU never gets the signal to hand control over.

It also satisfies the basic requirements of mutual exclusion fairly cleanly. Only one process is in the critical section at a time, execution inside it is effectively atomic, and no external force can interrupt it for the duration.

Why This Feels Like Cheating
Interrupt disabling does not really "solve" mutual exclusion through clever algorithm design. It brute-forces it by simply making the CPU incapable of doing anything else. It is the equivalent of locking the entire office building instead of just locking a single filing cabinet. It works, but the side effects are severe.

Where It Falls Apart

Despite the simplicity, this method has enough problems that it is not a general-purpose solution.

ProblemWhat Happens
Clock DriftThe system clock is driven by timer interrupts. If interrupts are disabled for too long, the clock drifts and loses accuracy. Anything that depends on correct timing starts misbehaving.
Multi-Core FailureOn multiprocessor systems, disabling interrupts on one CPU does nothing to stop another CPU from accessing the same shared data. To make it work, you would need to disable interrupts on every CPU simultaneously, which is slow and defeats the purpose of having multiple cores.
System FreezeIf a process stays inside the critical section too long with interrupts disabled, the whole system effectively freezes. Keyboard input stops registering, mouse events get dropped, and scheduled tasks pile up.
Security RiskIf user-level programs were allowed to disable interrupts, any poorly written or malicious program could lock up the entire system. For this reason, only the OS kernel is permitted to use this mechanism.
Real-Time FailureReal-time systems depend on precise timing and fast responses to external events. Disabling interrupts breaks both of those requirements, making this approach completely unsuitable.

Where It Is Still Used

Despite its limitations, interrupt disabling is not completely obsolete. There are a few narrow scenarios where it still makes sense:

  • Inside the kernel itself, for very short and specific operations that need to be atomic (like updating a scheduler data structure).
  • Embedded systems with a single processor and simple requirements, where the overhead of semaphores or mutexes is unnecessary.
  • As a building block inside spinlock implementations, where interrupts are disabled on a single core for the duration of the lock to prevent deadlocks caused by interrupt handlers trying to acquire the same lock.

But for anything involving multiple cores, heavy multitasking, or real-time constraints, other synchronization tools like locks, semaphores, and monitors have long taken over.

Understanding this technique is still worth the time though. The concept behind it, blocking external interference to protect shared state, is the same concept that all modern synchronization mechanisms are built on, just implemented in more sophisticated ways.

The Golden Rule
Even when interrupt disabling is justified (like inside the kernel), the critical section must be kept as short as humanly possible. Every microsecond with interrupts disabled is a microsecond where the system cannot respond to hardware events, network packets, or user input.
Mutual Exclusion Using Interrupt Disabling

How interrupt disabling protects the critical section on a uniprocessor system

Interrupt Disabling Knowledge Check

Question 1 of 1

Test your understanding of when interrupt disabling works and when it fails.

A system has 4 CPU cores. Process A disables interrupts on Core 1 and enters a critical section that accesses shared variable X. Can Process B, running on Core 3, still access variable X?
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.