COMP 3150Operating Systems

01 Introduction

Most computers have far more processes than CPUs. Even a modest laptop has hundreds of processes running at any moment; a data-centre server may have thousands. At each instant, the operating system's scheduler decides which of the ready processes gets to use a CPU core, and for how long. This is one of the most consequential decisions the kernel makes — it determines the system's throughput, its responsiveness, its fairness, and the experience of every user interacting with it.

The scheduling problem has no single best answer. A batch system wants to complete as many jobs per hour as possible. An interactive system wants every keystroke to feel instantaneous. A real-time system must guarantee that operations complete by specific deadlines. A fair-share system wants each user to receive their promised slice of the machine. Every scheduler is a design in which some goals are favoured at the expense of others.

This lesson establishes the vocabulary of scheduling without yet presenting the specific algorithms. It defines the problem, describes the three levels at which scheduling decisions are made, introduces the metrics used to compare policies, and lays out the fundamental trade-offs. Unit 5 builds directly on this foundation — the algorithms it presents are all concrete responses to the problem and metrics defined here.

Prerequisites

This lesson builds on the process state model from Lesson 3.2 and the PCB from Lesson 3.3. In particular, the distinction between Ready and Blocked is essential — the scheduler only ever chooses among processes in the Ready state. If that distinction is not yet clear, review Lesson 3.2 before continuing.

02 Learning objectives

By the end of this lesson you will be able to

  • Explain scheduling goals.
  • Describe schedulers.
  • Define scheduling metrics.
  • Analyse performance.
  • Compare approaches.

This lesson contributes to U3.4 and to course learning outcomes CLO3 and CLO6. It prepares the ground for Unit 5.

03 Required reading

  • Operating System Concepts — Chapter 5, Sections 5.1 and 5.2 (Basic Concepts and Scheduling Criteria). The classical introduction to the scheduling problem and the metrics used to evaluate it.
  • OSTEP — Chapter 7, Scheduling: Introduction, especially the discussion of workload assumptions and metrics. OSTEP's treatment of the metrics is more explicit than the classical text.
  • Love, R. — Linux Kernel Development, 3rd ed., Chapter 4 (Process Scheduling). The Linux perspective on why scheduling exists and what the kernel cares about.
  • Linux man pages: man 7 sched (the overview of Linux's scheduling policies), man 1 nice, man 2 sched_setscheduler, man 1 chrt. These document the scheduling interface available from user space.

Reading strategy

Read Silberschatz Section 5.1–5.2 first for the formal framing of the problem and the metrics. Then read OSTEP Chapter 7's introduction for the same ideas presented more concretely. The Linux-specific material is best read with the terminal open — the man pages for sched and nice are worth consulting while reading section 4.9.

04 Core content

4.1 The scheduling problem

At its simplest, the scheduling problem is: given a set of ready processes and a limited number of CPUs, decide which process runs next on which CPU. The decision must be made repeatedly, at every moment when a CPU becomes available or a higher-priority process becomes ready.

Four things make this harder than it first appears:

  1. Different workloads want different things. A batch compute job wants long uninterrupted time slices; an interactive terminal wants a quick response after every keystroke. A scheduler that is ideal for one is poor for the other.
  2. The future is unknown. A scheduler cannot know in advance how long a process will run before blocking, or how soon a currently-blocked process will become ready. It must decide based on what it can observe.
  3. The system changes continuously. Processes arrive and depart, block and unblock, in patterns that the scheduler cannot fully predict or control.
  4. The decision has a cost. The scheduler runs on the very CPU it is allocating. Every cycle it spends deciding is a cycle no process is running. A policy that is theoretically optimal but computationally expensive may be worse in practice than a simpler approximate policy.

The rest of this lesson develops the vocabulary needed to reason about these trade-offs: what schedulers exist, when they run, what they try to achieve, and how to measure whether they succeed.

4.2 CPU–I/O burst behaviour

A useful empirical observation underpins most scheduling design: a process alternates between bursts of CPU activity and bursts of I/O activity. It computes for a while, then reads or writes, then computes again, and so on. The distribution of burst lengths is characteristically bimodal — most bursts are short (a few milliseconds) and a few are long.

Two extreme profiles capture the ends of the spectrum:

CPU-bound process
Spends most of its time computing, with occasional I/O to read input or write output. Scientific simulations, video transcoders, and compilers while they are parsing are examples. These processes benefit from long, uninterrupted time slices — each context switch is a small cost that matters less if the slice is long.
I/O-bound process
Spends most of its time waiting for I/O, with brief bursts of CPU activity to process the data that arrives. Shells waiting for input, web servers waiting for requests, and text editors while you are typing are examples. These processes benefit from being scheduled promptly after their I/O completes, so they can issue the next request and get back to waiting — a delay here wastes the device as well as the CPU.

Most real programs fall somewhere on the spectrum between these two extremes, and a single program's position may change over its lifetime. A compiler is CPU-bound while parsing and generating code, but becomes I/O-bound while reading source files and writing object files. A web server is I/O-bound during request handling but CPU-bound during a JSON parse.

This matters to the scheduler because the two profiles want different things. A scheduler that gives CPU-bound processes long slices and I/O-bound processes quick dispatch after blocking is doing the right thing for both. A scheduler that treats them identically will be mediocre at both. The classical observation is that a good scheduler should favour I/O-bound processes when they become ready — they will block again quickly, freeing the CPU for others while keeping the device busy.

4.3 The three levels of schedulers

Traditional operating-systems theory distinguishes three schedulers that operate on different timescales and manage different aspects of the process lifecycle. Modern general-purpose kernels often blur the boundaries — Linux implements the first as an implicit policy and the third as part of the memory manager — but the three-way distinction remains useful for understanding what "scheduling" means.

The three levels of process scheduler A diagram showing the process lifecycle with three schedulers interacting with it. The long-term scheduler admits processes from the job pool into the ready queue. The short-term scheduler dispatches ready processes onto the CPU. The medium-term scheduler swaps processes between the ready queue and a suspended state on disk. THE THREE LEVELS OF SCHEDULER Job pool new processes on disk long-term admission Ready queue processes in memory, ready to run short-term dispatch CPU one process at a time per core Suspended swapped out to disk (frees physical memory) medium-term swap out / swap in Timescales long-term: seconds to minutes between decisions short-term: hundreds to thousands of times per second medium-term: seconds to minutes, driven by memory pressure
Figure 3.4 — The three levels of scheduler. Modern general-purpose kernels typically implement the long-term role implicitly and the medium-term role as a concern of the memory manager.
Long-term scheduler (job scheduler)
Decides which processes in the job pool are admitted into the ready queue. Runs infrequently — seconds or minutes between decisions. Its primary role is controlling the degree of multiprogramming: the number of processes resident in memory at once. On batch systems this matters a lot; on interactive and mobile systems it is often implicit, with every newly created process simply being admitted. Linux does not have a distinct long-term scheduler — when you run a program, it is admitted immediately unless a resource limit intervenes.
Short-term scheduler (CPU scheduler)
Decides which ready process runs on the CPU next. Runs very frequently — on the order of hundreds to thousands of times per second on a busy system. Its speed matters directly to system performance, because every microsecond it spends deciding is a microsecond no process is running. When textbooks or this course use the word "scheduler" unqualified, they almost always mean this one.
Medium-term scheduler
Decides which processes to swap out of memory (to a suspended state on disk) and which to bring back. Its purpose is to control memory pressure when the degree of multiprogramming exceeds what fits in physical memory. In modern systems this role is largely absorbed into the virtual-memory subsystem — the page-replacement policy discussed in Module 3 acts as a fine-grained version of what the medium-term scheduler used to do at process granularity.

Why "scheduler" usually means the short-term one

The three schedulers act on very different timescales. The long-term scheduler makes maybe a handful of decisions per minute; the medium-term scheduler is driven by memory pressure and may go quiet for long stretches. The short-term scheduler runs constantly — thousands of decisions per second on a loaded server. It is the one whose algorithm has the largest effect on everyday system behaviour, and it is the one that most of the course's scheduling material is about.

4.4 When scheduling decisions are made

The short-term scheduler does not run continuously. It runs at specific points where a decision is required. There are exactly four such points in a general-purpose system:

  1. When a running process blocks. The process issues a blocking system call (for example, read on a slow device) and moves from Running to Blocked. The CPU is now idle and must be given to another process. This is a voluntary scheduling event — the process chose to give up the CPU.
  2. When a running process is preempted. The timer interrupt fires, or a higher-priority process becomes ready, and the kernel decides the current process should stop running. The process moves from Running to Ready. This is an involuntary event — the process did not ask to give up the CPU.
  3. When a blocked process becomes ready. An I/O completion or a signal moves a process from Blocked to Ready. The scheduler may decide to preempt the current process in favour of the newly ready one, or may let the current process continue.
  4. When a running process terminates. The process exits. The CPU is now idle and must be given to another process. This is again a voluntary event.

Two of these four events (blocking and termination) are initiated by the running process itself; they always require the scheduler to run because the CPU is genuinely idle. The other two (preemption and a blocked process becoming ready) are opportunities for the scheduler to run: it may choose to switch processes, or it may not.

4.5 Preemptive versus non-preemptive scheduling

This distinction is fundamental and worth stating explicitly.

Non-preemptive scheduling
Once a process is running, it continues until it voluntarily yields — by blocking on I/O, by exiting, or by explicitly giving up the CPU. The scheduler only runs when the running process asks for it. Simple, low-overhead, but vulnerable to a process that never yields: a CPU-bound process with no I/O will monopolise the CPU until it terminates.
Preemptive scheduling
The scheduler can interrupt a running process at any time, typically on a timer tick or when a higher-priority process becomes ready. Requires hardware support (a timer) and considerable care in the kernel, since kernel data structures may be in an inconsistent state when preemption occurs. Modern general-purpose kernels are preemptive.

The transition Running → Ready from Lesson 3.2 is only possible in a preemptive scheduler. In a non-preemptive scheduler, that transition does not exist — a process can only leave the Running state by blocking or terminating. This is one of the reasons the state diagram in Lesson 3.2 was drawn with preemption as an explicit transition: it is a design choice, not a universal property of all operating systems.

Preemption is what makes modern systems responsive. Without it, a single runaway process could freeze the machine for minutes. With it, the kernel can reclaim the CPU at a known maximum interval — typically every 1–10 ms — and give other processes a turn. The cost is the complexity of writing kernel code that is safe to preempt, and the overhead of the resulting context switches.

4.6 Scheduling metrics

To compare scheduling policies, we need quantitative measures. Five metrics appear throughout the literature, and each measures a different aspect of the scheduler's behaviour. No single policy optimises all of them, and understanding which one matters for a given workload is essential to reasoning about a scheduler's design.

Standard scheduling metrics
Metric Definition Favoured by
CPU utilisation Fraction of time the CPU is doing useful work (as opposed to idle). Everyone — idle CPUs waste expensive hardware.
Throughput Number of processes completed per unit of time. Batch systems and servers.
Turnaround time Time from process submission to its completion. Batch systems and short jobs.
Waiting time Total time the process spends in the ready queue (i.e., waiting for the CPU, not blocked). All systems — it is the piece of turnaround the scheduler controls directly.
Response time Time from submission to the first response (first output, not completion). Interactive and real-time systems.

The most important distinction: turnaround vs. response

Turnaround and response time differ subtly but importantly. Turnaround measures when the process finishes. Response measures when the process starts producing output. A word processor's response time is how long until the first character appears on screen; its turnaround is how long until you exit. For interactive work, response time dominates — users do not care when a task eventually finishes as long as it feels responsive throughout. For batch work, turnaround dominates — the total time to completion is what matters. A scheduler that optimises one does not automatically optimise the other, and the choice between them shapes the whole design.

4.7 Computing the metrics

For a process with submission time S, first-run time F, completion time C, and total CPU burst length B, the metrics are:

turnaround = C - S
waiting    = turnaround - B
response   = F - S

A small worked example will make these definitions concrete.

Computing metrics for a three-process workload

Consider three processes, all arriving at time t = 0:

Process Arrival Burst
P108
P204
P302

Assume the scheduler runs them in the order P1, P2, P3, one after the other (the first-come, first-served order that Unit 5 will formalise).

P1: starts 0, ends 8
P2: starts 8, ends 12
P3: starts 12, ends 14

Per-process metrics:

Process   Turnaround  Waiting  Response
  P1          8           0        0
  P2         12           8        8
  P3         14          12       12

Average turnaround = (8 + 12 + 14) / 3 = 11.33
Average waiting    = (0 + 8 + 12) / 3  = 6.67
Average response   = (0 + 8 + 12) / 3  = 6.67

Now consider the same three processes in the order P3, P2, P1:

P3: starts 0, ends 2
P2: starts 2, ends 6
P1: starts 6, ends 14

Process   Turnaround  Waiting  Response
  P1         14          6        6
  P2          6          2        2
  P3          2          0        0

Average turnaround = (14 + 6 + 2) / 3 = 7.33
Average waiting    = (6 + 2 + 0) / 3  = 2.67
Average response   = (6 + 2 + 0) / 3  = 2.67

The same three processes, with identical total work, produce dramatically different metrics depending only on the order in which they run. Average turnaround drops from 11.33 to 7.33; average waiting drops from 6.67 to 2.67. This is why scheduling policy matters: order alone can change the metrics by a factor of two.

The order that produced the better results was shortest-job- first — the small process finished quickly, then the medium one, then the large one. Unit 5 will show that this ordering is optimal for average waiting time among non-preemptive policies, and will examine the trade-offs that come with it (such as starvation of the large process if many short jobs keep arriving).

4.8 Fundamental trade-offs

Every scheduling policy makes trade-offs among the metrics and between the two process classes. Three trade-offs are worth stating explicitly because they recur throughout the course.

Throughput versus latency

Running processes for long uninterrupted slices maximises throughput, because context-switch overhead is amortised over more useful work. But long slices increase response time for other processes, because each one waits longer before its first turn. The trade-off is quantitative: a slice that is twice as long doubles the throughput benefit per switch but doubles the average wait before the first dispatch.

Fairness versus priority

A perfectly fair scheduler gives every process an equal share of the CPU. But a process doing important work — say, a real-time audio decoder, or a kernel thread reclaiming memory under pressure — may need more CPU than a background indexing job. Prioritising one over the other is unfair but useful. Every production scheduler balances the two: some degree of fairness for ordinary work, with escape hatches for processes that legitimately need more.

Overhead versus decision quality

A scheduler that gathers more information can make better decisions, but the gathering itself costs CPU time. The scheduler runs on the very resource it is allocating, so every cycle it uses is a cycle not available to processes. A perfect algorithm that took a millisecond per decision would be useless at the thousands-of-decisions-per-second rate the short-term scheduler runs. Real schedulers are designed for constant-time or logarithmic-time decisions.

These trade-offs are not incidental to scheduling design — they are the reason there is no universal "best" scheduler. Every policy makes choices, and every choice has consequences that show up in some metric.

4.9 Workload assumptions

Before evaluating a scheduler, it is worth being explicit about what the workload is assumed to look like. Formal analysis of scheduling algorithms relies on simplifying assumptions that make the problem tractable. The common ones are:

  • Each job runs for the same amount of time.
  • All jobs arrive at the same time.
  • Once started, each job runs to completion (no preemption, no blocking).
  • All jobs use only the CPU (no I/O).
  • Run times are known in advance.

Real workloads violate every one of these assumptions. Jobs have wildly different durations, arrive at irregular times, block on I/O, and their future behaviour is unknown. The assumptions are useful as starting points — they let us prove what a scheduler can do under ideal conditions — but their violation is what makes scheduling an engineering problem rather than a mathematical one.

Unit 5 builds on this by presenting each algorithm with its assumptions stated explicitly. Seeing how a policy behaves when its assumptions are relaxed is one of the most valuable exercises in understanding why real systems make the choices they do.

4.10 How this connects to the PCB

Every one of these concepts has a concrete representation in the process control block from Lesson 3.3. The scheduling fields of the PCB are what the scheduler actually reads and writes on every decision:

  • The state field determines whether a process is a scheduling candidate at all — only Ready processes are.
  • Priority and nice values express the process's relative importance, encoding the fairness-versus- priority trade-off.
  • Recent CPU usage (or virtual runtime, on Linux) is the scheduler's measure of how much of the CPU the process has had lately, used to determine fairness.
  • Time slice remaining tracks how much of the current quantum is left before the timer will force preemption.
  • Accounting fields such as nvcsw and nivcsw record how many times the process has been voluntarily or involuntarily switched, providing evidence of its workload profile.

When the scheduler runs, it is essentially reading these fields from every ready PCB, applying its policy, and updating the winning process's fields — plus a few others — to reflect the new state. The metric definitions and the policy design are abstractions over exactly this data flow.

4.11 Linux and the scheduling interface

Linux implements the concepts from this lesson with several specific scheduling policies and a user-visible interface for influencing them. The full picture belongs to Unit 5, but the high-level structure is worth previewing here.

Linux's scheduler supports several scheduling policies:

  • SCHED_OTHER — the default, fair-share policy for ordinary processes. Implemented by the Completely Fair Scheduler (CFS), which we will examine in Unit 5.
  • SCHED_BATCH — a variant of SCHED_OTHER for CPU-bound background work; the scheduler is slightly less eager to preempt these processes, favouring throughput over latency.
  • SCHED_IDLE — the lowest priority; runs only when nothing else is runnable.
  • SCHED_FIFO and SCHED_RR — real-time policies that run at a higher priority than any SCHED_OTHER process. The difference between them is whether a running real-time task can be preempted by another of the same priority (RR, with a time slice) or not (FIFO). These require CAP_SYS_NICE to set and are reserved for work that genuinely needs deterministic scheduling.
  • SCHED_DEADLINE — a deadline-based policy in which each task declares its runtime, deadline, and period. The scheduler guarantees that tasks meet their deadlines if the system is schedulable at all.

From user space, the priority of a SCHED_OTHER process can be adjusted with nice and renice, and the policy of a process can be queried and changed with chrt or sched_setscheduler. The man pages for these tools are the practical entry point to the Linux scheduler.

# Show the scheduling policy and priority of a process
$ chrt -p $$
pid 4321's current scheduling policy: SCHED_OTHER
pid 4321's current scheduling priority: 0

# Run a command at a lower priority (higher nice value)
$ nice -n 10 some_cpu_intensive_command

# Change the policy of a running process (requires privileges for RT policies)
$ sudo chrt -f 50 -p 4321

The numbers that appear here — nice values, priorities, real- time priorities — are exactly the fields from the PCB that the scheduler reads on every decision. The interface exists so that users and administrators can influence the trade-offs this lesson has described.

05 Worked example

To make the metrics and the trade-offs concrete, compare three schedulers on the same workload and observe the different results.

Same workload, three different policies

Consider five processes, all arriving at t = 0:

Process Burst
P110
P22
P36
P41
P54

Order 1 — arrival order (P1, P2, P3, P4, P5):

P1: 0–10, P2: 10–12, P3: 12–18, P4: 18–19, P5: 19–23

Wait times:  0, 10, 12, 18, 19        avg = 11.8
Response:    0, 10, 12, 18, 19        avg = 11.8
Turnaround: 10, 12, 18, 19, 23        avg = 16.4

Order 2 — shortest burst first (P4, P2, P5, P3, P1):

P4: 0–1, P2: 1–3, P5: 3–7, P3: 7–13, P1: 13–23

Wait times:  0, 1, 7, 3, 13           avg = 4.8
Response:    0, 1, 7, 3, 13           avg = 4.8
Turnaround:  1, 3, 7, 13, 23          avg = 9.4

Order 3 — longest burst first (P1, P3, P5, P2, P4):

P1: 0–10, P3: 10–16, P5: 16–20, P2: 20–22, P4: 22–23

Wait times:  0, 20, 10, 22, 16        avg = 13.6
Response:    0, 20, 10, 22, 16        avg = 13.6
Turnaround: 10, 22, 16, 23, 20        avg = 18.2

Comparison:

Order Avg wait Avg response Avg turnaround
Arrival11.811.816.4
Shortest first4.84.89.4
Longest first13.613.618.2

The shortest-first ordering produces metrics that are roughly half those of the arrival ordering, and roughly a third of the longest-first ordering. Total work is identical in all three cases; only the sequence of decisions changed. This is the observation that motivates the study of scheduling algorithms: the choice of order can dominate every metric the system cares about.

Notice, however, what the shortest-first policy does to the long P1: it waits until every other process has finished. If P1 were an interactive process — the browser you are using — waiting 13 units while four short jobs complete would produce a frozen interface. Shortest-first is optimal for average waiting but terrible for the worst case. This is the fairness-versus-efficiency trade-off in a single example.

06 Interactive activity

Activity · observe scheduling decisions on Linux

Open a terminal in your course VM and work through the following. The goal is to see the concepts of this lesson in action on a running system.

  1. See the run queue. Run cat /proc/loadavg. The three numbers are the 1-, 5-, and 15-minute load averages — roughly, the average length of the run queue on the system. What is the load on your VM right now? What does this tell you about how many processes are competing for the CPU?
  2. See context-switch activity.
    $ cat /proc/schedstat | head -1
    # The first line gives system-wide scheduler statistics,
    # including the number of context switches since boot.
    Run it twice a few seconds apart. How many switches occurred in the interval? Divide by the time interval to get switches per second.
  3. See the metrics for a command.
    $ time ls /usr/bin | wc -l
    The time command reports three numbers: real time (turnaround), user CPU time, and system CPU time. The difference between real time and CPU time is the time the process spent waiting — scheduled out, blocked on I/O, or waiting for input.
  4. Compare a CPU-bound and an I/O-bound process. Start a CPU-bound process:
    $ yes > /dev/null &
    $ PID_CPU=$!
    Now start an I/O-bound process:
    $ find / -type f > /dev/null 2>&1 &
    $ PID_IO=$!
    After a few seconds, run:
    $ for p in $PID_CPU $PID_IO; do
        echo "PID $p:"
        awk '{print "  utime:", $14, "stime:", $15, "nvcsw:", $42, "nivcsw:", $43}' /proc/$p/stat
    done
    Which process has accumulated more CPU time? Which has more voluntary context switches? Which has more involuntary ones? Explain the differences in terms of the burst model.
  5. Change a process's priority.
    $ renice +10 -p $PID_CPU
    $ ps -p $PID_CPU -o pid,ni,pri,stat
    The nice value changed. Watch the CPU usage in top — does the CPU-bound process receive less CPU now? What does this tell you about the fairness aspect of Linux's scheduler?
  6. Observe preemption.
    $ vmstat 1 5
    The cs column shows context switches per second. Watch it before, during, and after starting several CPU-bound processes. The number of involuntary context switches will increase as the scheduler preempts the competing processes at each timer tick.
  7. View a process's scheduling policy.
    $ chrt -p $$
    This shows the policy of the current shell. It should be SCHED_OTHER. Then try to see the policy of a process you do not own — the kernel restricts this information, but the command should explain the error.
  8. Clean up.
    $ kill $PID_CPU $PID_IO

Reflect: which of the five metrics from section 4.6 is most visible in each observation? Which is hardest to see directly? Why?

07 Knowledge check

Check your understanding

Question 1

A web server and a scientific simulation run on the same machine. Which scheduling metrics matter most for each, and why?

Show answer
The web server cares most about response time and throughput: requests should be answered quickly, and many requests should be served per second. The simulation cares most about turnaround time and CPU utilisation: it wants to finish as soon as possible and use as much CPU as possible while running. A scheduler that optimises for the server (short time slices, frequent preemption) may slightly penalise the simulation, and vice versa. The right choice depends on which workload the system is primarily for — which is why modern systems use policy mechanisms to distinguish them (SCHED_BATCH for the simulation, SCHED_OTHER for the server).

Question 2

Why does the short-term scheduler run so much more frequently than the long-term scheduler, and why does that matter?

Show answer
The short-term scheduler chooses among ready processes every time a CPU becomes available — which happens on every preemption, every blocking system call, and every process exit, often hundreds or thousands of times per second. The long-term scheduler decides only when a process should be admitted to the ready queue, which happens on process creation — typically seconds apart. The frequency matters because the short-term scheduler runs on the very CPU it is allocating: every cycle it spends deciding is a cycle lost. Its algorithm must therefore be very fast — constant-time or logarithmic-time — which constrains the complexity of scheduling policies. This is one of the reasons no real system implements a provably optimal but expensive scheduling algorithm.

Question 3

A scheduler achieves 100% CPU utilisation but very high average waiting time. Is this possible? Explain.

Show answer
Yes. CPU utilisation measures how busy the CPU is, not how fairly it is shared. A single long-running process could keep the CPU 100% busy while every other process waits. More generally, a scheduler that favours long jobs will achieve high utilisation (little time spent switching) while starving shorter jobs. Utilisation and waiting time measure different properties of the schedule and can be driven in opposite directions. This is a concrete instance of the throughput-versus-latency trade-off from section 4.8.

Question 4

Why does a good scheduler favour I/O-bound processes when they become ready, and how does this relate to the burst model?

Show answer
An I/O-bound process has just completed an I/O operation and is ready to run a brief CPU burst — typically processing the data that arrived and issuing the next request. If the scheduler dispatches it promptly, it will use a small amount of CPU and then block again, freeing the CPU for other processes and (crucially) keeping the I/O device busy. Delaying it wastes the device as well as the CPU. This is a consequence of the burst model: I/O-bound processes naturally give up the CPU quickly, so favouring them costs the scheduler little while improving both CPU utilisation and device throughput. A scheduler that treats I/O-bound and CPU-bound processes identically will delay the I/O-bound ones unnecessarily, which is why the classical algorithms often incorporate a preference based on recent burst behaviour.

Question 5

In the worked example, the shortest-first ordering produced the best average metrics. Why, then, do real systems not simply adopt it?

Show answer
Two reasons. First, the burst lengths are not known in advance. In the worked example, we knew every process's burst length because we invented it; a real scheduler does not. It can estimate future bursts from past behaviour, but the estimates are imperfect. Second, shortest-first starves long jobs. In the example, P1 waited 13 units — the longest of any process. If the workload is such that many short jobs keep arriving, the long job could wait indefinitely. For interactive processes this is unacceptable: a user's browser would freeze. Real systems therefore use approximations to shortest-first (Linux's CFS approximates it through virtual runtime) combined with aging mechanisms that ensure no process is starved. The example's point is that ordering matters, not that shortest-first is universally correct.

08 Unit discussion

Discussion prompt

Mobile operating systems such as Android and iOS face a scheduling environment radically different from a traditional server: battery life is precious, thermal throttling is constant, and the user's perception of responsiveness is paramount. Some of the metrics from this lesson matter much more; others matter less.

Which of the five metrics — CPU utilisation, throughput, turnaround, waiting time, response time — would you prioritise for a mobile OS? Which would you de-prioritise? Justify your choices with reference to the constraints of a mobile device, and consider how the trade-offs from section 4.8 look different when the "cost" being minimised is battery drain rather than CPU time.

Post your response to the Unit 3 discussion forum and reply to at least two classmates. Supports CLO3 and CLO7.

09 Practice exercise

This ungraded exercise consolidates the lesson and prepares you for the scheduling work in Lab 4 and Unit 5. Aim to spend 45–60 minutes on it.

  1. Compute metrics by hand. Four processes arrive at t = 0 with burst times 4, 6, 8, and 10. Compute average turnaround, average waiting, and average response under three orderings: as listed, sorted shortest-first, and sorted longest-first. Which ordering wins on each metric?
  2. Vary arrival times. Repeat the computation with arrival times 0, 2, 4, 6 for the same four processes. Does the shortest-first ordering still win? Explain why the arrival times change the result.
  3. Classify a live workload. Run top in interactive mode and sort by CPU (P). Which processes are CPU-bound and which are I/O-bound? What is the difference in their typical CPU percentages? Then sort by time (T) and note which processes have accumulated the most CPU time — these are the long-running CPU consumers.
  4. Write a scheduler simulator (small). Write a C program that reads a list of (arrival, burst) pairs from standard input and prints the average turnaround, waiting, and response times under a chosen algorithm. Start with the simplest possible algorithm — service in arrival order — and verify it produces the expected results for the worked example in this lesson. This program will be the seed for the larger simulator in Lab 4 and Assignment 2.
  5. Compare policies empirically. Modify the simulator to accept a command-line argument selecting the policy: arrival, shortest-first, or longest-first. Run all three on the same workload and compare the metrics. How large is the difference? Does the difference grow with the spread of burst times?
  6. Reflect. In your own words, explain why the scheduler cannot simply look at every process's burst length and pick the shortest, and give two consequences that follow from this limitation.

10 Summary

  • The scheduling problem: given a set of ready processes and limited CPUs, decide which runs next. No single best answer — different workloads want different things.
  • Processes alternate between CPU bursts and I/O bursts. I/O-bound processes benefit from prompt scheduling after blocking; CPU-bound processes benefit from long time slices.
  • Three levels of scheduler: long-term (admission), short-term (CPU dispatch), and medium-term (swapping). The short-term scheduler is what this course usually means by "scheduler."
  • Scheduling decisions are made at four points: process blocks, process is preempted, blocked process becomes ready, process terminates.
  • Preemptive schedulers can interrupt running processes; non-preemptive schedulers cannot. Modern general-purpose kernels are preemptive and require hardware timer support.
  • Five metrics: CPU utilisation, throughput, turnaround time, waiting time, response time. Turnaround measures when a process finishes; response measures when it first produces output.
  • Every scheduling policy trades among metrics and between process classes. The three fundamental trade-offs are throughput vs. latency, fairness vs. priority, and overhead vs. decision quality.
  • Formal analysis assumes simplifying workloads that real systems violate. The assumptions are useful as starting points, but their violation is what makes scheduling an engineering problem.

Looking ahead

Lesson 3.5 examines the mechanism that makes preemptive scheduling possible — the context switch — and quantifies its cost. Unit 5 then presents the specific algorithms (first-come first-served, shortest-job-first, priority, round robin, multilevel queues) that populate every operating-systems textbook.

11 References

  • Silberschatz, A., Galvin, P. B., & Gagne, G. Operating System Concepts, 10th ed., Chapter 5, Sections 5.1–5.2.
  • Arpaci-Dusseau, R. H., & Arpaci-Dusseau, A. C. Operating Systems: Three Easy Pieces, Chapter 7. Available online at ostep.org.
  • Love, R. Linux Kernel Development, 3rd ed., Chapter 4 (Process Scheduling). Addison-Wesley, 2010.
  • Linux man-pages: man 7 sched, man 1 nice, man 1 renice, man 1 chrt, man 2 sched_setscheduler, man 5 proc (the sched file).
  • Bach, M. J. The Design of the UNIX Operating System, Chapter 7. Prentice Hall, 1986. (Classical presentation of the three-level scheduler model.)
👤