04. Real-Time & Multiprocessor Scheduling

In batch and interactive systems, scheduling algorithms optimize for statistical averages: mean turnaround time, maximum throughput, or average interactive response time. However, two specialized computing domains introduce physical and temporal constraints that break standard general-purpose queuing models:

1. Real-Time Scheduling Foundations

Real-time systems are categorized by the operational consequence of missing a deadline:

The Periodic Task Formal Model

A classic real-time system executes a set of n periodic tasks, denoted Τ = {τ1, τ2, ..., τn}. Each task τi is characterized by three deterministic physical parameters:

Total CPU Utilization (Load Factor, U):
The fraction of CPU execution bandwidth demanded by the periodic task set is the sum of their individual utilization ratios:
U = ∑i=1n (Ci / Pi)
Necessary Condition for Schedulability:
For any single-core hardware architecture, the task set cannot possibly be scheduled without missing deadlines if total utilization exceeds 100%:
U ≤ 1.0
If U > 1.0, the task set is mathematically unschedulable under any algorithm.

2. Rate-Monotonic Scheduling (RMS)

Developed by C. L. Liu and James Layland (1973), Rate-Monotonic Scheduling (RMS) is the canonical static-priority scheduling algorithm for periodic real-time tasks:

The Liu & Layland Schedulability Bound

Is a task set with U ≤ 1.0 guaranteed to meet all deadlines under RMS? No. Because priorities are fixed statically, a long-period task can be repeatedly preempted by short-period tasks, missing its deadline even when spare CPU capacity exists.

Liu and Layland proved that a set of n independent periodic tasks is guaranteed to be schedulable under Rate-Monotonic Scheduling if its total CPU utilization satisfies the following inequality:

U = ∑i=1n (Ci / Pi) ≤ n(21/n − 1)
Evaluating the bound across increasing task counts: The 69.3% Invariant: If total utilization of any arbitrary periodic task set is below 69.3%, Rate-Monotonic scheduling guarantees that no deadline will ever be missed. If utilization falls between 69.3% and 100%, the set may still be schedulable, but requires exact Response-Time Analysis (RTA) recurrence testing.

3. Earliest Deadline First (EDF)

To overcome the 69.3% static priority ceiling and achieve up to 100% CPU utilization, operating systems turn to Earliest Deadline First (EDF).

The Optimality of EDF

Theorem: Earliest Deadline First is an optimal dynamic uniprocessor scheduling algorithm. A set of periodic tasks with deadlines equal to periods is schedulable under EDF if and only if:

U = ∑i=1n (Ci / Pi) ≤ 1.0 (100%)

EDF can fully saturate a processor execution core up to 100% capacity without missing a single deadline.

The Fatal Flaw of EDF: Domino Effect under Overload

Despite its theoretical optimality, EDF exhibits a dangerous vulnerability in mission-critical environments: the cascading domino effect during transient overloads.

Interactive Stepper: Static RMS vs. Dynamic EDF under High Utilization

Workload Arc Task 1 (C1=2, P1=5; U1=0.40) and Task 2 (C2=4, P2=7; U2=0.57). Total U = 0.97 (97%). Testing schedulability against the Liu & Layland bound (82.8%).
Timeline Clock T = 0 ms
Active Core Task Task 1 (C=2, P=5)
Next Urgent Deadline Task 1 (d = 5 ms)
Schedulability Status Nominal (Zero Misses)
TASK 1 [C1=2ms, P1=5ms | Priority: High / Period: 5ms] TASK 2 [C2=4ms, P2=7ms | Priority: Low / Period: 7ms] CPU CORE 0 (Combined Dispatch Timeline) 0 2 T=5 (T1) T=7 (T2) T=10 (T1) T=14 (T2)
Current Step Summary At T=0, both Task 1 and Task 2 release instances. Under RMS, Task 1 (period 5) has shorter period than Task 2 (period 7), so Task 1 takes top static priority.
What Is Happening

Task 1 runs on Core 0 from T=0 to T=2 ms. Task 2 waits in the Ready list.

Why The System Does This

RMS assigns highest priority to the shortest period task (P1=5 < P2=7) to ensure high-frequency events complete ahead of longer deadlines.

4. Multiprocessor Scheduling (SMP Architectures)

Modern processors do not scale through raw clock frequency increases; they scale horizontally through multiple physical CPU cores. Symmetric Multiprocessing (SMP) architectures share a unified physical address space across all cores, but introduce complex hardware topology and memory latency bottlenecks.

Single-Queue vs. Multi-Queue Topologies

Operating system architects face a foundational design fork when structuring multiprocessor runqueues:

Figure 4.1: Single-Queue (SQMS) vs. Multi-Queue (MQMS) Topologies
Comparing global lock contention against per-core cache affinity and work-stealing load balancing.
Single-Queue Multiprocessor (SQMS) Global Runqueue [Spinlock Protected] Extreme lock contention beyond 4 cores Core 0 Cold Cache Core 1 Cold Cache Core 2 Cold Cache • Tasks bounce across cores, destroying hardware caches. Multi-Queue Multiprocessor (MQMS) Runqueue 0 (Local Lock) Core 0 (L1/L2 Warm) Runqueue 1 (Local Lock) Core 1 (L1/L2 Warm) Steal • Zero lock contention; exceptional cache affinity. • Requires Work Stealing to balance idle cores.

Hardware Cache Affinity & Invalidation Overhead

When a process runs on Core 0, its instructions and working data are fetched into Core 0's private L1 and L2 silicon caches. The task runs at peak hardware speed.

If the scheduler preempts the task and subsequently dispatches it onto Core 1:

To prevent this, production schedulers enforce Processor Affinity:

NUMA-Aware Scheduling (Non-Uniform Memory Access)

On modern multi-socket enterprise servers and high-core-count processors (such as AMD EPYC and Intel Xeon), memory controllers are partitioned across distinct physical silicon dies called NUMA Nodes.

Work Stealing Algorithms

To maintain near-perfect load balance in MQMS without global lock contention, modern schedulers implement Work Stealing:

  1. Each CPU core maintains its own double-ended queue (deque) of runnable tasks.
  2. A core pushes and pops tasks from the head of its own deque in LIFO order, maximizing hardware L1 cache locality for recently paused sub-tasks.
  3. When a core exhausts its own runqueue and becomes idle, it randomly chooses a peer core (the "victim") and attempts to steal work from the tail of the victim's deque in FIFO order.
  4. Stealing from the tail minimizes lock conflicts with the victim core (which accesses the head), while simultaneously grabbing the oldest queued task—the task whose cache footprint on the victim core is already cold, making cross-core migration practically free.