Course Project Cis 342
Course Project Cis 342
Information Sciences
Department of Computer
Science Operating System
NOVEMBER 8, 2024
Operating System COURSE PROJECT CIS 342
11/8/2024
Introduction
In this study, seven scheduling policies were evaluated through controlled experiments.
These policies, encompassing Round-Robin (RR) with varying quantum lengths, First-
Come, First-Serve (FCFS), Shortest Job First Preemptive (SJF Preemptive), and Shortest
Remaining Time First (SRTF), represent a cross-section of modern CPU scheduling
techniques. Each policy was assessed in terms of its structure, response characteristics, and
performance, with a particular focus on average waiting time across different workloads. The
purpose of this analysis is to understand how variations in scheduling approaches impact
system efficiency, including responsiveness and resource allocation.
Round-Robin scheduling with various quantum sizes can have different impacts on how
processes are executed and completed
The CPU, like every part of the computer has a task to perform, as well as a set of
instructions on how to perform such tasks. Since a numerous amount of programs can be in
memory at the same time, the CPU needs a sequence of functionality; that’s where the
process manager comes in. The Process manager handles the removal of the running process
from the CPU and the selection of another process.
The OS maintains all Process in scheduling Queues. It maintains a separate queue for each of
the process states and when the state of a process is changed, it is unlinked from its current
queue and moved to its new state queue.
1
Operating System COURSE PROJECT CIS 342
11/8/2024
Job queue − This queue keeps all the processes in the system.
Ready queue − This queue keeps a set of all processes that are in memory, and are
waiting to be executed
Device queues − The processes which are blocked due to unavailability of an I/O
device constitute this queue.
The OS can use different scheduling algorithms to manage each queue. The process manager
determines how to move processes between the ready and run queues which can only have
one entry per processor core on the system.
There are six popular methods of scheduling processes to the CPU, which are:
First Come, First Serve
Shortest Job First
Priority Scheduling
Shortest Remaining Time
Round Robin(RR)
Multiple-Level Queues
Scheduling Criteria
CPU utilization - Ideally the CPU would be busy 100% of the time, so
as to waste 0 CPU cycles. On a real system CPU usage should range from
40% (lightly loaded ) to 90% ( heavily loaded. )
Throughput - Number of processes completed per unit time.
Turnaround time - Time required for a particular process to complete, from
submission time to completion
Waiting time - How much time processes spend in the ready queue waiting their turn
to get on the CPU.
Response time - The time taken in an interactive program from the issuance of a
command to the commence of a response to that command.
In brief:
Arrival Time: Time at which the process arrives in the ready queue. Completion Time:
Time at which process completes its execution. Burst Time: Time required by a process for
2
Operating System COURSE PROJECT CIS 342
11/8/2024
CPU execution. Turn Around Time: Time Difference between completion time and arrival
time. Turn Around Time = Completion Time – Arrival Time
Waiting Time(W.T): Time Difference between turnaround time and burst time. Waiting
Time = Turn Around Time – Burst Time
Input data
Process Arrival Time Burst Time (BT)
No. (AT)
1 0 20
2 2 30
3 4 10
4 6 15
3
Operating System COURSE PROJECT CIS 342
11/8/2024
4
Operating System COURSE PROJECT CIS 342
11/8/2024
4. Round-Robin with Quantum equal to 10,000
Execution:
The quantum size is excessively large compared to the burst times of the processes.
Each process will receive more than enough time to complete its execution in a single
go.
5
Operating System COURSE PROJECT CIS 342
11/8/2024
6
Operating System COURSE PROJECT CIS 342
11/8/2024
Characteristics: Minimizes average waiting time; however, it may lead to starvation of
longer processes.
7
Operating System COURSE PROJECT CIS 342
11/8/2024
8
Operating System COURSE PROJECT CIS 342
11/8/2024
Discussion
Performance Comparison:
FCFS is not efficient when implementing in a system, where processes have varying burst
time, as long processes will take up a lot of time before the short processes are executed.
SJF has a low average waiting time but it may encounter starvation problem if the longer
processes arrive unless all the impending processes duration are known.
SRTF is also better in waiting time as we also have seen that we can preempt the process but
it comes at the cost of high context switch.
As for variability, RR demonstrates dependence on the length of the quantum. A small value
provides better response time but incurs more context switch overheads and a large value
provides poor response time and starts acting like FCFS.
Preemptive vs. Non-preemptive:
Other scheduling techniques like preemptive scheduling (e.g., SRTF) can actually lowers
down the waiting time greatly for short processes but it also has much overhead.
The non-preemptive algorithms are easier and the overhead is smaller but the response
period of some processes may be longer.
Conclusion
Findings: Which scheduling algorithm should be used depends on the functionality that is
required by the system (e.g. is the system required to be fair, will it need to be fast, does it
need to provide high throughput).
Recommendations:
For real-time systems a smaller quantum RR or preemptive scheduling like SRTF may be
desirable to be adopted.
For batch processing, SJF gives low average number of waiting times.
FCFS should be used when there is more emphasis on the ease of the implemented
scheduling algorithm than on the execution time.
9
Operating System COURSE PROJECT CIS 342
11/8/2024
Code:
Shortest Remaining Time
#include <stdio.h>
void calculateAverages(int wt[], int tat[], int n, double *avg_wt, double *avg_tat) {
double totalWaitingTime = 0, totalTurnAroundTime = 0;
for (int i = 0; i < n; i++) {
totalWaitingTime += wt[i];
totalTurnAroundTime += tat[i];
}
*avg_wt = totalWaitingTime / n;
*avg_tat = totalTurnAroundTime / n;
printf("Average Waiting Time: %.2f\n", *avg_wt);
printf("Average Turnaround Time: %.2f\n\n", *avg_tat);
}
void calculateSRTF(int at[], int bt[], int n, double *avg_wt, double *avg_tat) {
int wt[n], tat[n];
10
Operating System COURSE PROJECT CIS 342
11/8/2024
int time = 0, completed = 0, shortest = -1;
int remaining_bt[n];
int isCompleted[n];
for (int i = 0; i < n; i++) {
remaining_bt[i] = bt[i];
isCompleted[i] = 0;
}
while (completed != n) {
shortest = -1;
for (int i = 0; i < n; i++) {
if (at[i] <= time && !isCompleted[i]) {
if (shortest == -1 || remaining_bt[i] < remaining_bt[shortest]) {
shortest = i;
}
}
}
if (shortest == -1) {
time++;
continue;
}
remaining_bt[shortest]--;
time++;
if (remaining_bt[shortest] == 0) {
wt[shortest] = time - at[shortest] - bt[shortest];
tat[shortest] = time - at[shortest];
isCompleted[shortest] = 1;
completed++;
}
11
Operating System COURSE PROJECT CIS 342
11/8/2024
}
printf("SRTF Scheduling:\n");
for (int i = 0; i < n; i++) {
printf("Process %d - Waiting Time: %d, Turnaround Time: %d\n", i + 1, wt[i], tat[i]);
}
calculateAverages(wt, tat, n, avg_wt, avg_tat);
}
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
int at[n], bt[n];
for (int i = 0; i < n; i++) {
printf("Enter the arrival time of process %d: ", i + 1);
scanf("%d", &at[i]);
printf("Enter the burst time of process %d: ", i + 1);
scanf("%d", &bt[i]);
}
double avg_wt_srtf, avg_tat_srtf;
calculateSRTF(at, bt, n, &avg_wt_srtf, &avg_tat_srtf);
printf("=====================\n");
printf("Summary of Average Waiting Times:\n");
printf("SRTF - Average Waiting Time: %.2f\n", avg_wt_srtf);
return 0;
}
Round Robin(RR):
#include <climits>
12
Operating System COURSE PROJECT CIS 342
11/8/2024
#include <iostream>
#include <vector>
using namespace std;
struct Process {
int AT, BT, WT, FT, TAT, pos;
vector<int> ST;
};
int main() {
int n, i, j, quant;
if (quant <= 0) {
cout << "Quantum must be greater than 0. Please enter a valid quantum." << endl;
return 1; // Exit the program
}
cout << "Enter the arrival time of processes: " << endl;
for (i = 0; i < n; i++) {
cin >> p[i].AT;
}
cout << "Enter the burst time of processes: " << endl;
for (i = 0; i < n; i++) {
cin >> p[i].BT;
p[i].ST.reserve(20);
}
int c = n;
float time = 0;
vector<float> b(n), a(n);
int tot_wt = 0, tot_tat = 0;
while (c > 0) {
int index = -1;
float mini = INT_MAX;
14
Operating System COURSE PROJECT CIS 342
11/8/2024
flag = false;
if (!flag) {
time++;
continue;
}
p[index].ST.push_back(time);
if (b[index] > 0) {
a[index] = time + 0.1;
}
15
Operating System COURSE PROJECT CIS 342
11/8/2024
if (b[index] == 0) {
c--;
p[index].FT = time;
p[index].WT = p[index].FT - p[index].AT - p[index].BT;
tot_wt += p[index].WT;
p[index].TAT = p[index].BT + p[index].WT;
tot_tat += p[index].TAT;
}
}
cout << p[i].FT << "\t\t" << p[i].WT << "\t\t" << p[i].TAT << endl;
}
double avg_wt = tot_wt / static_cast<double>(n);
double avg_tat = tot_tat / static_cast<double>(n);
16
Operating System COURSE PROJECT CIS 342
11/8/2024
cout << "The average wait time is: " << avg_wt << endl;
cout << "The average turnaround time is: " << avg_tat << endl;
return 0;
}
Shortest Job First
#include <stdio.h>
void calculateAverages(int wt[], int tat[], int n, double *avg_wt, double *avg_tat) {
double totalWaitingTime = 0, totalTurnAroundTime = 0;
*avg_wt = totalWaitingTime / n;
*avg_tat = totalTurnAroundTime / n;
printf("Average Waiting Time: %.2f\n", *avg_wt);
printf("Average Turnaround Time: %.2f\n\n", *avg_tat);
}
void calculateSJF(int at[], int bt[], int n, double *avg_wt, double *avg_tat) {
int wt[n], tat[n];
int time = 0, completed = 0, shortest = -1;
int remaining_bt[n];
int isCompleted[n];
17
Operating System COURSE PROJECT CIS 342
11/8/2024
for (int i = 0; i < n; i++) {
remaining_bt[i] = bt[i];
isCompleted[i] = 0;
}
while (completed != n) {
shortest = -1;
for (int i = 0; i < n; i++) {
if (at[i] <= time && !isCompleted[i]) {
if (shortest == -1 || remaining_bt[i] < remaining_bt[shortest]) {
shortest = i;
}
}
}
if (shortest == -1) {
time++;
continue;
}
time += remaining_bt[shortest];
wt[shortest] = time - at[shortest] - bt[shortest];
tat[shortest] = wt[shortest] + bt[shortest];
remaining_bt[shortest] = 0;
isCompleted[shortest] = 1;
completed++;
}
18
Operating System COURSE PROJECT CIS 342
11/8/2024
printf("SJF Scheduling:\n");
for (int i = 0; i < n; i++) {
printf("Process %d - Waiting Time: %d, Turnaround Time: %d\n", i + 1, wt[i], tat[i]);
}
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
printf("=====================\n");
printf("Summary of Average Waiting Times:\n");
printf("SJF - Average Waiting Time: %.2f\n", avg_wt_sjf);
19
Operating System COURSE PROJECT CIS 342
11/8/2024
return 0;
}
First Come, First Serve
#include <stdio.h>
void calculateAverages(int wt[], int tat[], int n, double *avg_wt, double *avg_tat) {
double totalWaitingTime = 0, totalTurnAroundTime = 0;
*avg_wt = totalWaitingTime / n;
*avg_tat = totalTurnAroundTime / n;
printf("Average Waiting Time: %.2f\n", *avg_wt);
printf("Average Turnaround Time: %.2f\n\n", *avg_tat);
}
void calculateFCFS(int at[], int bt[], int n, double *avg_wt, double *avg_tat) {
int start[n], wt[n], tat[n];
int currentTime = 0;
if (at[0] != 0) {
currentTime = at[0];
} else {
currentTime = 0;
}
20
Operating System COURSE PROJECT CIS 342
11/8/2024
start[0] = currentTime;
wt[0] = 0;
printf("FCFS Scheduling:\n");
for (int i = 0; i < n; i++) {
printf("Process %d - Waiting Time: %d, Turnaround Time: %d\n", i + 1, wt[i], tat[i]);
}
21
Operating System COURSE PROJECT CIS 342
11/8/2024
scanf("%d", &n);
return 0;
}
Multiple-Level Queues
#include <stdio.h>
#define MAX_PROCESSES 20
#define SYSTEM_QUEUE 0
#define USER_QUEUE 1
22
Operating System COURSE PROJECT CIS 342
11/8/2024
// Structure to represent a process
typedef struct {
int process_id;
int burst_time;
int queue_type; // 0 for System, 1 for User
int waiting_time;
int turnaround_time;
} Process;
// Function to calculate waiting time and turnaround time for all processes
void calculateWaitingAndTurnaroundTimes(Process processes[], int n) {
processes[0].waiting_time = 0; // First process has no waiting time
processes[0].turnaround_time = processes[0].burst_time; // Turnaround time is the burst
time for the first process
// Main function
int main() {
Process processes[MAX_PROCESSES];
int n;
// Sort processes based on queue type (system processes first, followed by user processes)
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (processes[i].queue_type > processes[j].queue_type) {
// Swap processes
Process temp = processes[i];
processes[i] = processes[j];
processes[j] = temp;
}
}
25
Operating System COURSE PROJECT CIS 342
11/8/2024
}
// Calculate and print average waiting time and average turnaround time
float total_waiting_time = 0, total_turnaround_time = 0;
for (int i = 0; i < n; i++) {
total_waiting_time += processes[i].waiting_time;
total_turnaround_time += processes[i].turnaround_time;
}
printf("\nAverage Waiting Time: %.2f", total_waiting_time / n);
printf("\nAverage Turnaround Time: %.2f\n", total_turnaround_time / n);
return 0;
}
Priority Scheduling
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
26
Operating System COURSE PROJECT CIS 342
11/8/2024
using namespace std;
27
Operating System COURSE PROJECT CIS 342
11/8/2024
}
}
28
Operating System COURSE PROJECT CIS 342
11/8/2024
}
}
int main() {
int n;
cout << "Enter the number of processes: ";
cin >> n;
vector<Process> processes(n);
// Print the average waiting time and turnaround time with 2 decimal precision
cout << fixed << setprecision(2);
cout << "Average Waiting Time: " << avg_waiting << endl;
cout << "Average Turnaround Time: " << avg_turnaround << endl;
return 0;
}
30