COMP 3150Operating Systems

01 Lab overview

CourseCOMP 3150 / CMIS 3150 — Operating Systems
UnitUnit 5 — CPU Scheduling
Weight1.25% of the final grade (1/12 of the 15% laboratory component)
Estimated duration4–5 hours of hands-on work
SubmissionOne archive containing the simulator's source, the Makefile, the workload files, the metrics' output, and a short report (see § 06)
EnvironmentLinux VM, gcc, make, python3 (for plotting), gnuplot or matplotlib (optional)

This lab contributes to U5.1 through U5.5, and to course learning outcomes CLO3, CLO5, and CLO8.

02 Learning objectives

By the end of this laboratory you will be able to

  • Implement FCFS, SJF, SRTF, priority, and Round Robin scheduling algorithms.
  • Compute the standard scheduling metrics (waiting, turnaround, response, throughput, CPU utilisation).
  • Run each algorithm on the same workloads and compare their behaviour.
  • Analyse the effect of the time quantum on Round Robin's metrics.
  • Explain the trade-offs between average metrics and fairness, and between predictability and throughput.

03 Background

3.1 The scheduler's model

The simulator models the classical CPU scheduling problem. A process is a tuple (pid, arrival, burst, priority). The scheduler selects one process at a time to run on a single CPU. The scheduler's decisions are captured by the process's timeline: the intervals during which the process runs.

3.2 Metrics

Waiting time
The total time a process spends in the ready queue (i.e., ready but not running). Computed as turnaround − burst.
Turnaround time
The total time from a process's arrival to its completion. Computed as completion − arrival.
Response time
The time from a process's arrival to its first scheduling. For interactive workloads, this is more informative than the turnaround time.
Throughput
The number of processes completed per unit time.
CPU utilisation
The fraction of time the CPU is busy, total_burst / wall_clock_interval.
Fairness
Informally, the extent to which processes of the same priority receive comparable service. Quantified by the variance of the waiting times and by the maximum waiting time.

3.3 The algorithms

FCFS
First Come, First Served — non-preemptive; the process that arrived first runs to completion.
SJF
Shortest Job First — non-preemptive; the process with the shortest burst is selected next.
SRTF
Shortest Remaining Time First — preemptive SJF; the process with the shortest remaining burst is selected at every scheduling point.
Priority
Non-preemptive; the process with the highest priority runs to completion. In the simulation, lower numbers mean higher priority.
Round Robin
Preemptive; processes run in arrival order, each for at most one time quantum, then go to the back of the ready queue.

3.4 The workload file format

The simulator reads workloads from plain text files, one process per line:

# pid  arrival  burst  priority
1      0        7      3
2      2        4      1
3      4        1      2
4      5        4      4
          

Lines beginning with # are comments; blank lines are ignored.

04 Guided activities

Activity 4.1 — The skeleton and the FCFS scheduler

  1. Create the lab directory and download the starter skeleton (or build it yourself following the specification below):
    mkdir -p ~/comp3150/lab4 && cd ~/comp3150/lab4
  2. Implement the process structure and the workload reader. The structure should be:
    typedef struct {
        int   pid;
        int   arrival;
        int   burst;
        int   priority;
        int   remaining;      /* for preemptive algorithms */
        int   start;          /* first dispatch, -1 if not dispatched */
        int   completion;     /* -1 if not completed */
        int   waiting;        /* accumulated waiting time */
    } process_t;
  3. Implement the FCFS scheduler. It selects, at each scheduling point, the arrived process with the smallest arrival time; ties are broken by PID.
  4. Write the metric computation: for each process, compute the waiting time, the turnaround time, and the response time; then compute the averages and the CPU utilisation.
  5. Test FCFS on the workload from § 3.4. Your output should include, for each process, the start time, the completion time, and the three metrics.

Activity 4.2 — SJF and SRTF

  1. Implement SJF: at each scheduling point, select the arrived process with the smallest burst. Ties are broken by arrival, then by PID.
  2. Implement SRTF: at every unit of time, check whether a newly arrived process has a smaller remaining burst than the running process; if so, preempt. Ties are broken by arrival, then by PID.
  3. Run both on the workload from § 3.4. Compare the average waiting times. Which algorithm performs better on this workload, and why?

Activity 4.3 — Priority scheduling

  1. Implement non-preemptive priority: at each scheduling point, select the arrived process with the smallest priority number. Ties are broken by arrival, then by PID.
  2. Run it on the workload. What is the average waiting time?
  3. Construct a workload in which a long, low-priority process arrives first and a stream of short, high-priority processes arrives after it. Observe the low-priority process's waiting time and discuss starvation.

Activity 4.4 — Round Robin and the time quantum

  1. Implement Round Robin with a parameter q for the time quantum. At each quantum's expiry, the running process goes to the back of the ready queue; the next process in arrival order is dispatched.
  2. Run it on the workload with q = 1, q = 2, q = 4, and q = 8. Record the average waiting time, the average turnaround time, and the average response time for each.
  3. Plot the four metrics as functions of q. What happens as q grows? What happens as q approaches the largest burst? Explain the two limits.

Activity 4.5 — Comparing all algorithms on multiple workloads

  1. Create four workload files:
    • workload-cpu-bound.txt — 10 processes, all with long bursts (50–200 ms).
    • workload-io-bound.txt — 10 processes, all with short bursts (1–10 ms).
    • workload-mixed.txt — 5 long bursts and 5 short bursts interleaved.
    • workload-interactive.txt — 10 processes, each with several short bursts and one long burst, mimicking an interactive session.
  2. Run all five algorithms on all four workloads. Record the average metrics in a table.
  3. For each workload, identify the algorithm that minimises the average waiting time and the algorithm that minimises the average response time. Are they the same? Explain.
  4. Repeat with SRTF and Round Robin (with a small quantum such as 2) and confirm that SRTF is optimal for average waiting time (given the actual burst times) while Round Robin is comparable but not optimal.

05 Exercises

  1. Convoy effect. Construct a workload that produces the FCFS convoy effect: one long process arrives first, then many short processes. Run FCFS, SJF, and Round Robin. Show the metrics and explain quantitatively how the convoy effect penalises the short processes.
  2. Starvation. Construct a workload that starves a process under priority scheduling. Then modify the priority scheduler to use ageing: after every quantum a process waits, its priority improves by one (i.e., its priority number decreases). Show that the starvation is eliminated and quantify the cost in average waiting time.
  3. Multilevel feedback queue. Design and implement a simplified MLFQ with three levels: level 0 (highest priority) gets a quantum of 2, level 1 gets 4, level 2 (lowest) runs to completion. A process that exhausts its quantum at level i is demoted to level i+1; a process that blocks (i.e., uses less than its quantum) stays at its level. Run the MLFQ on the workload-interactive.txt and compare it to SRTF and Round Robin.
  4. Lottery scheduling. Implement lottery scheduling: each process holds tickets, and at each scheduling point the scheduler draws a random ticket. Give the short processes three tickets and the long processes one, and show that the CPU share is proportional to the tickets over a long run.
  5. Multicore scheduling. Extend the simulator to model two CPUs. Run each algorithm with two CPUs and compare the speedup to the single-CPU run. Discuss why the speedup is never exactly 2× and identify the algorithm that scales best.
  6. Real measurements. Write a small C program that forks n CPU-bound children and measures their wall-clock times under Linux's default scheduler. Compare the observed throughput to the simulator's predictions for the same workload and explain the discrepancies (the kernel's scheduler is more sophisticated than the classical algorithms).

06 Deliverables

Submit a single archive named lab4-<lastname>-<studentnumber>.tar.gz containing:

  • The simulator's C source (sched.c or a small set of files), with your name and student number at the top.
  • The Makefile with a default target building the simulator and a clean target.
  • The four workload files from Activity 4.5.
  • metrics.txt — the complete metrics' table for all algorithms on all workloads, with the commands that produced it.
  • plots/ — the plots from Activity 4.4 (Round Robin's metrics as functions of the quantum) and any additional plots you generate.
  • report.md (or report.pdf) — the lab report described below.

Lab report

The report should be 4–6 pages (excluding code) and contain:

  • Design. A brief description of the simulator's architecture: the process structure, the ready queue, the scheduling loop, the metric computation.
  • Algorithm implementations. For each algorithm, a short description, the pseudocode, and the code fragment that implements the scheduling decision.
  • Results. The metrics' tables and plots. For each workload, identify the best algorithm for each metric and explain why the algorithm performs as it does.
  • Analysis. A discussion of the trade-offs: SJF/SRTF optimise average waiting time but are unfair and require knowledge of burst times; Round Robin is fairer and provides good response time but is not optimal for throughput; Priority scheduling risks starvation and can be improved by ageing.
  • Reflection. A short discussion of the gap between the classical algorithms and the Linux kernel's CFS, and of why real systems do not simply use SRTF.
  • 07 Grading rubric

    Lab 4 grading rubric (100 points)
    Criterion Points CLOs Exemplary (90–100%) Proficient (80–89%) Developing (70–79%)
    Algorithm correctness 35 CLO3, CLO5 All five algorithms implemented correctly, including preemption, ties, and edge cases. Algorithms mostly correct; minor issues on preemption or tie-breaking. Several algorithms produce incorrect schedules or metrics.
    Metrics computation 20 CLO3 All metrics computed correctly; verification with hand-worked examples provided. Metrics correct with occasional arithmetic slips. Metrics computed but with a systematic error (e.g., wrong response time definition).
    Experimental design and analysis 20 CLO3, CLO5 Workloads are varied and well-chosen; analysis is quantitative and considers all metrics. Workloads and analysis are adequate but not exhaustive. Analysis is superficial or fails to compare algorithms on a common basis.
    Report quality 15 CLO8 Report is well-structured, evidence-based, and the trade-offs discussion is insightful. Report is clear; some claims not fully supported. Report is disorganised or makes unsupported claims.
    Code quality 10 CLO6, CLO8 Code is modular, readable, and free of leaks and undefined behaviour. Code is readable with minor style issues. Code is monolithic or has memory-safety issues.

    Late submission penalty: 10% per day, up to a maximum of three days, after which the lab is accepted only with documented extenuating circumstances.

    08 Knowledge check

    Check your understanding

    Question 1

    Consider the workload in § 3.4. Compute the average waiting time under FCFS, SJF, and SRTF. Which is the smallest, and why?

    Show answer
    FCFS: the processes run in arrival order: P1 (0–7), P2 (7–11), P3 (11–12), P4 (12–16). Waiting times are P1 = 0, P2 = 5, P3 = 7, P4 = 7; average = 4.75. SJF: the shortest burst among the arrived processes is selected at each point. At time 0 only P1 has arrived, so P1 runs to completion (0–7). At time 7, the arrived processes are P2 (4), P3 (1), P4 (4); SJF selects P3 (7–8). Then P2 (8–12), then P4 (12–16). Waiting times are P1 = 0, P2 = 6, P3 = 3, P4 = 7; average = 4.0. SRTF: at each unit of time the process with the shortest remaining burst is selected. At time 0 only P1 is ready, so P1 starts. At time 2, P2 arrives with remaining 4 < P1's remaining 5, so P2 preempts P1 and runs (2–6). At time 4, P3 arrives with remaining 1 < P2's remaining 0? No: P2 has been running for 2 units of its 4, so its remaining is 2; P3's burst is 1, which is smaller, so P3 preempts P2 and runs (6–7). Then P2 resumes (7–9), then P1 resumes (9–14), then P4 (14–18). Waiting times: P1 = 0 + (14−9) = 5, P2 = 2 + (7−6) = 3, P3 = 3, P4 = 9; average = 5.0. The calculations show that on this particular workload SJF has the smallest average waiting time, consistent with the classical result that SJF is optimal among non-preemptive algorithms.

    Question 2

    In Round Robin, what happens to the average waiting time as the time quantum grows to infinity? What happens as it approaches zero? Give the limiting algorithm in each case.

    Show answer
    As the quantum grows to infinity, Round Robin becomes FCFS: every process runs to completion within its first quantum, so the schedule is the arrival order. As the quantum approaches zero, Round Robin becomes processor sharing: every process runs for an infinitesimal slice in a round-robin order, so the schedule approaches interleaved execution at a very fine granularity. In the limit, every process receives the same fraction of the CPU at every instant, which is the ideal fairness bound. The cost of the infinitesimal quantum is the context-switch overhead: each switch takes time, and when the quantum is very small the CPU spends most of its time switching and little time running processes. Between the two limits, the quantum is a trade-off: a larger quantum reduces the switching overhead but increases the response time; a smaller quantum improves the response time but increases the overhead.

    Question 3

    Why is SRTF not used in a real general-purpose operating system, even though it is optimal for average waiting time?

    Show answer
    SRTF requires knowledge of the actual remaining burst time of every process at every scheduling point. In a real system, burst times are not known in advance: they depend on the workload, the input data, the cache state, the I/O pattern, and the hardware. The system can only estimate them, and an estimate that is wrong makes SRTF's optimality disappear. In addition, SRTF can starve long processes: if short processes keep arriving, a long process may never run. The Linux kernel's Completely Fair Scheduler (CFS) takes a different approach: it gives each runnable process a "virtual runtime" that increases as the process runs, and it always runs the process with the smallest virtual runtime — a form of weighted fair queuing that does not require burst-time knowledge and provides fairness as well as good average metrics.

    Question 4

    What is the convoy effect? Which algorithm suffers from it, and which algorithm(s) mitigate it?

    Show answer
    The convoy effect is the phenomenon in FCFS scheduling where a single long process at the head of the ready queue causes all the short processes behind it to wait for the long process to complete. The short processes, which could have completed quickly, are delayed by the long process's burst time, so their waiting times (and the average waiting time) are much larger than necessary. SJF and SRTF mitigate the convoy effect by selecting the shortest process first, so the short processes complete quickly and the long process runs at the end. Round Robin also mitigates the effect, though less directly: by interleaving the processes, every process makes progress and no process waits for the long process to complete before receiving any service.

    Question 5

    Suppose the simulator's average waiting time for SJF on a workload is 3.4 ms, and for SRTF on the same workload it is 4.1 ms. Is this possible? Explain the conditions under which SJF can outperform SRTF on the average waiting time.

    Show answer
    Yes, this is possible. SRTF is optimal for average waiting time when preemption is free and when the burst times are known exactly. On a specific workload, SJF (which runs a process to completion once started) can produce a better average waiting time than SRTF (which preempts) if the preemptions cause the simulator to accumulate waiting time in the wrong processes. Consider a workload where a long process arrives first and several short processes arrive a bit later: SRTF preempts the long process, so the long process accumulates waiting time in small increments while the short processes run. SJF, by contrast, runs the long process to completion and then serves the short processes back to back, so the long process's waiting time is 0 and the short processes' waiting times are bounded by the long process's burst. Which average is smaller depends on the numbers. The classical optimality result for SRTF holds in the long run when the workload is stationary and preemption is free; on a finite workload with a specific arrival pattern, SJF can win.

    09 References

    • Silberschatz, A., Galvin, P. B., & Gagne, G. Operating System Concepts, 10th ed., Chapter 5.
    • Arpaci-Dusseau, R. H., & Arpaci-Dusseau, A. C. Operating Systems: Three Easy Pieces, Chapters 7–10.
    • Tanenbaum, A. S., & Bos, H. Modern Operating Systems, 4th ed., Chapter 2.
    • Linux kernel documentation: CFS Scheduler (Documentation/scheduler/sched-design-CFS.rst).
    • Linux man-pages: man 7 sched, man 2 sched_setscheduler, man 1 taskset, man 1 nice, man 1 chrt.
    👤