Assignment 03: CPU Scheduling Algorithms
I. Objective & Theoretical Framework
This assignment explores the mechanisms by which an operating system manages multiprogramming. You will simulate various CPU scheduling algorithms to determine how processes in the ready queue are allocated CPU time, calculating the turnaround time and waiting time for each.
You will implement the following scheduling policies assuming all processes arrive at the same time:
- First-Come, First-Served (FCFS): Processes are executed strictly according to their arrival time irrespective of other parameters.
- Shortest Job First (SJF): Processes are executed according to the length of their burst time; if burst times are equal, FCFS is applied.
- Round Robin (RR): A preemptive approach where time slices are assigned to each process in equal portions and in circular order, ensuring every process gets an equal chance.
- Priority: Processes are executed according to assigned priority values; ties are resolved using FCFS.
II. Prerequisite Knowledge & Resources
- Metrics:
- Waiting Time (WT): The total time a process spends waiting in the ready queue.
- Turnaround Time (TAT): The total time taken from process submission to process completion ($TAT = WT + \text{Burst Time}$).
- Standard Libraries:
<stdio.h>for standard input/output. - Array Manipulation: Deepen your understanding of sorting arrays in C, as SJF and Priority scheduling require dynamic rearrangement of process queues.
III. Starter Code & Partial Implementations
The following skeleton demonstrates the logic for calculating Waiting Time and Turnaround Time in an FCFS environment where all processes are assumed to arrive at time 0. Use this as the baseline for constructing the other algorithms.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <burst_time_1> <burst_time_2> ...\n", argv[0]);
return 1;
}
int n = argc - 1;
int bt[20], wt[20], tat[20];
float wtavg = 0, tatavg = 0;
for(int i = 0; i < n; i++) {
bt[i] = atoi(argv[i+1]); // Convert string arguments to integers
}
// FCFS Wait Time and Turnaround Time Logic
wt[0] = 0;
tat[0] = bt[0];
for(i = 1; i < n; i++) {
wt[i] = wt[i-1] + bt[i-1];
tat[i] = tat[i-1] + bt[i];
}
for(i = 0; i < n; i++) {
wtavg += wt[i];
tatavg += tat[i];
}
printf("\nAverage Waiting Time: %f", wtavg / n);
printf("\nAverage Turnaround Time: %f\n", tatavg / n);
return 0;
}
IV. Step-by-Step Task List
FCFS Implementation: Complete the starter code above to display a formatted table outputting the Process ID, Burst Time, Waiting Time, and Turnaround Time for every process, matching the calculations.
SJF Implementation: Create a new program for SJF. Before calculating
wtandtat, implement a sorting algorithm (like Bubble Sort) to arrange the processes in ascending order based on their CPU burst times.Priority Implementation: Create a new program. Prompt the user for both Burst Time and a Priority value for each process. Sort the queue based on the Priority value before executing the calculations.
Round Robin Implementation: Create a new program. Prompt the user for a time slice (quantum) size. Use a
whileloop to iteratively deduct the time slice from the burst time of each process in a circular fashion until all burst times reach zero.
V. Common Pitfalls & Debugging Strategies
Uncoupled Array Sorting: When sorting processes by burst time (SJF) or priority, you must simultaneously swap the corresponding Process IDs in a parallel array. If you only sort the burst times, you will lose track of which burst time belongs to which process.
Round Robin Infinite Loops: In Round Robin, ensure you are tracking the remaining burst time in a temporary array. If you deduct the time slice directly from the original burst time array without a separate tracker, you lose the data needed to calculate the final Turnaround Time.
Arrival Time Assumption: Be explicitly aware that these foundational implementations assume an arrival time of
0for all processes.
VI. Real-World Case Study
While foundational, these algorithms are highly applicable to complex computational environments like distributed systems and edge computing. In a network of edge nodes processing latency-sensitive tasks, schedulers must constantly balance workloads. A localized edge server might employ a variation of Shortest Job First to quickly clear lightweight data processing tasks (like sensor telemetry), preventing bottlenecking before sending heavier computational loads to the central cloud infrastructure.
- Algorithm Optimization Leaderboard: You will be provided with a hidden CSV dataset containing 10,000 randomized process requests (Arrival Time, Burst Time, Task Type). Your objective is to write the most highly optimized Shortest Job First (SJF) or Priority scheduler possible. The algorithms that clear the massive queue with the lowest average Turnaround Time and lowest CPU overhead will be ranked on the laboratory leaderboard.
VII. Advanced Variant Tasks
Multi-Level Queue Scheduling: Design a simulation where all processes in the system are divided into two distinct categories: System Processes and User Processes.
System processes must be given a higher absolute priority than user processes.
Utilize FCFS scheduling independently for the processes within each respective queue.
Dynamic Arrival Times: Modify your FCFS and SJF algorithms to accept unique arrival times for each process, rather than assuming they all arrive at time 0. Adjust your waiting time formulas accordingly.
VIII. Resources & Further Reading
- OSTEP - CPU Scheduling: Read Chapter 7: Scheduling Introduction (PDF) for a theoretical breakdown of Turnaround Time vs. Response Time under FCFS, SJF, and Round Robin.
- OSTEP - MLFQ: For advanced variant tasks, read Chapter 8: Multi-Level Feedback Queue (PDF).
- Real-World Load Balancing: CPU scheduling algorithms are the exact same mathematical models used to manage handover and data load balancing in dense LTE/5G network infrastructure. Understanding how a CPU clears its queue directly translates to how a cell tower manages concurrent user packets.