0% found this document useful (0 votes)
14 views12 pages

take code

code cpp

Uploaded by

Delight Chirume
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views12 pages

take code

code cpp

Uploaded by

Delight Chirume
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 12

#include <iostream>

#include <fstream>
#include <sstream>
#include <string>
#include <queue>
#include <climits>
#include <unistd.h>
#include <cstdlib>

using namespace std;

// Node structure for the Process linked list


struct Process {
int id, arrivalTime, burstTime, remainingBurstTime, priority;
int startTime, completionTime, turnAroundTime, waitingTime;
Process* next;
Process(int id, int arrival, int burst, int prio = 0)
: id(id), arrivalTime(arrival), burstTime(burst),
remainingBurstTime(burst), priority(prio),
startTime(-1), completionTime(0), turnAroundTime(0),
waitingTime(0), next(nullptr) {}
};
void insertProcess(Process*& head, int id, int arrival, int burst, int
priority);
void Results(Process* head, const string& outputFile);
void sjfPreemptive(Process* head);
void priorityNonPreemptive(Process* head);
void roundRobin(Process* head, int timeQuantum);
void firstComeFirstServe(Process* head);
void sjfNonPreemptive(Process* head);
void priorityPreemptive(Process* head);
void processFile(const string& inputFile, const string& outputFile, int
algorithm, int timeQuantum = 1);

//count processes
int countProcesses(Process* head) {
int processCount = 0;
for (Process* temp = head; temp != nullptr; temp = temp->next) {
processCount++;
}
return processCount;
}

// Function to insert a process into the linked list


void insertProcess(Process*& head, int id, int arrival, int burst, int
priority) {
// Dynamically allocate memory for a new process node
Process* newProcess = new(std::nothrow) Process(id, arrival, burst,
priority);//erro handling method that return a nullptr

// Check if nothrow returned a nullptr and handle the error


if (!newProcess) {
cerr << "Error: Memory allocation failed for process " << id <<
endl;
return;
}

// If the list is empty,the new process becomes the head


if (!head) {
head = newProcess;
} else {
// Otherwise, traverse to the end and add the new process
Process* temp = head;
while (temp->next) {
temp = temp->next;
}
temp->next = newProcess;
}
}

// Function to print results to an output file


void Results(Process* head, const string& outputFile, int
algorithmNumber) {
ofstream outFile(outputFile, ios::app); // Open in append mode to
add rows for each algorithm
if (!outFile) {
cerr << "Error: Could not open output file." << endl;
return;
}

// Write the algorithm number as the first column


outFile << algorithmNumber;

// Calculate waiting times and average


double totalWaitingTime = 0.0;
int processCount = 0;

for (Process* temp = head; temp != nullptr; temp = temp->next) {


outFile << ":" << temp->waitingTime; // Append waiting times
totalWaitingTime += temp->waitingTime;
processCount++;
}

// Append average waiting time in the last column


double averageWaitingTime = (processCount > 0) ? totalWaitingTime /
processCount : 0.0;
outFile << ":" << averageWaitingTime << endl;

outFile.close();
cout << "Results for algorithm " << algorithmNumber << " written to
'" << outputFile << "' successfully." << endl;
}

// SJF Preemptive Scheduling


void sjfPreemptive(Process* head) {
int processCount = countProcesses(head);
int currentTime = 0, completed = 0;
while (true) {
Process* shortestJob = nullptr;
int minBurst = INT_MAX;

for (Process* temp = head; temp != nullptr; temp = temp->next)


{
if (temp->arrivalTime <= currentTime && temp-
>remainingBurstTime > 0 && temp->remainingBurstTime < minBurst) {
minBurst = temp->remainingBurstTime;
shortestJob = temp;
}
}

if (shortestJob) {
if (shortestJob->startTime == -1) shortestJob->startTime =
currentTime;
shortestJob->remainingBurstTime--;
currentTime++;

if (shortestJob->remainingBurstTime == 0) {
shortestJob->completionTime = currentTime;
shortestJob->turnAroundTime = shortestJob-
>completionTime - shortestJob->arrivalTime;
shortestJob->waitingTime = shortestJob->turnAroundTime
- shortestJob->burstTime;
completed++;
}
} else {
currentTime++;
}

if (completed == processCount) break;

}}
// Priority Scheduling Non-Preemptive
void priorityNonPreemptive(Process* head) {
int processCount = countProcesses(head);
int currentTime = 0, completed = 0;
while (completed < processCount) {
Process* highestPriorityProcess = nullptr;
int highestPriority = INT_MAX;
for (Process* temp = head; temp; temp = temp->next) {
if (temp->arrivalTime <= currentTime && temp-
>remainingBurstTime > 0 && temp->priority < highestPriority) {
highestPriority = temp->priority;
highestPriorityProcess = temp;
}
}
if (highestPriorityProcess) {
highestPriorityProcess->startTime =
(highestPriorityProcess->startTime == -1) ? currentTime :
highestPriorityProcess->startTime;
currentTime += highestPriorityProcess->burstTime;
highestPriorityProcess->remainingBurstTime = 0;
highestPriorityProcess->completionTime = currentTime;
highestPriorityProcess->turnAroundTime = currentTime -
highestPriorityProcess->arrivalTime;
highestPriorityProcess->waitingTime =
highestPriorityProcess->turnAroundTime - highestPriorityProcess-
>burstTime;
completed++;
} else {
currentTime++;
}
}
}
// Round Robin Scheduling
void roundRobin(Process* head, int timeQuantum) {
queue<Process*> readyQueue;
int processCount=countProcesses( head);
int currentTime = 0, completed = 0;

for (Process* temp = head; temp; temp = temp->next)


if (temp->arrivalTime == 0) readyQueue.push(temp);

while (completed < processCount) {


if (!readyQueue.empty()) {
Process* current = readyQueue.front();
readyQueue.pop();

if (current->startTime == -1) current->startTime =


currentTime;
int timeSlice = min(timeQuantum, current-
>remainingBurstTime);
current->remainingBurstTime -= timeSlice;
currentTime += timeSlice;

for (Process* temp = head; temp; temp = temp->next)


if (temp->arrivalTime <= currentTime && temp-
>remainingBurstTime > 0 && temp != current)
readyQueue.push(temp);

if (current->remainingBurstTime > 0) {
readyQueue.push(current);
} else {
current->completionTime = currentTime;
current->turnAroundTime = current->completionTime -
current->arrivalTime;
current->waitingTime = current->turnAroundTime -
current->burstTime;
completed++;
}
} else {
currentTime++;
}
}
}
// First-Come-First-Serve Scheduling
void firstComeFirstServe(Process* head) {
int currentTime = 0, completed = 0;

// Traverse the list of processes to schedule them in arrival order


while (head) {
Process* current = head;

// If it's the first time this process is being executed, set


the start time
if (current->arrivalTime > currentTime) {
currentTime = current->arrivalTime; // Wait for the
process to arrive
}

current->startTime = currentTime;
currentTime += current->burstTime; // Add burst time to
current time for completion
current->completionTime = currentTime;
current->turnAroundTime = current->completionTime - current-
>arrivalTime;
current->waitingTime = current->turnAroundTime - current-
>burstTime;

completed++;
head = head->next; // Move to the next process in the list
}
}
// Shortest-Job-First Non-Preemptive Scheduling
void sjfNonPreemptive(Process* head) {
int processCount = countProcesses(head);
int currentTime = 0, completed = 0;

// Sort processes by arrival time, then by burst time


// Note: This assumes that the list is already ordered by arrival
time
while (completed < processCount) { // Assuming 4 processes for
completion check, can be dynamic
Process* shortestJob = nullptr;
int minBurst = INT_MAX;

// Find the process with the shortest burst time that has
arrived and not yet completed
for (Process* temp = head; temp != nullptr; temp = temp->next)
{
if (temp->arrivalTime <= currentTime && temp-
>remainingBurstTime > 0 && temp->remainingBurstTime < minBurst) {
minBurst = temp->remainingBurstTime;
shortestJob = temp;
}
}

// If a process is found, execute it


if (shortestJob) {
if (shortestJob->startTime == -1) {
shortestJob->startTime = currentTime;
}
currentTime += shortestJob->burstTime;
shortestJob->completionTime = currentTime;
shortestJob->turnAroundTime = shortestJob->completionTime -
shortestJob->arrivalTime;
shortestJob->waitingTime = shortestJob->turnAroundTime -
shortestJob->burstTime;
completed++;
} else {
currentTime++; // If no process is ready, just increment
the time
}
}
}

void priorityPreemptive(Process* head) {


int processCount = countProcesses(head);
int currentTime = 0, completed = 0;
while (completed < processCount) {
Process* highestPriorityProcess = nullptr;
int highestPriority = INT_MAX;

// Find the process with the highest priority that has arrived
and is still pending
for (Process* temp = head; temp; temp = temp->next) {
if (temp->arrivalTime <= currentTime && temp-
>remainingBurstTime > 0 && temp->priority > highestPriority) {
highestPriority = temp->priority;
highestPriorityProcess = temp;
}
}

if (highestPriorityProcess) {
// If it's the first time this process is being executed,
set the start time
highestPriorityProcess->startTime =
(highestPriorityProcess->startTime == -1) ? currentTime :
highestPriorityProcess->startTime;

// Execute the process by reducing its remaining burst time


highestPriorityProcess->remainingBurstTime--;
currentTime++;

// If the process has finished its execution


if (highestPriorityProcess->remainingBurstTime == 0) {
highestPriorityProcess->completionTime = currentTime;
highestPriorityProcess->turnAroundTime=
highestPriorityProcess->completionTime - highestPriorityProcess-
>arrivalTime;
highestPriorityProcess->waitingTime =
highestPriorityProcess->turnAroundTime - highestPriorityProcess-
>burstTime;
completed++;
}
}
else {
// If no process is available to run, just increment the
current time
currentTime++;
}
}
}

//Function to proces sthe input file


void processFile(const string& inputFile, const string& outputFile, int
algorithm, int timeQuantum) {
ifstream inFile(inputFile);
if (!inFile) {
cerr << "Error: Could not open input file." << endl;
return;
}

Process* head = nullptr;


string line;
int id = 0;

// Read input file and create linked list of processes


while (getline(inFile, line)) {
stringstream ss(line);
string value;
int arrivalTime, burstTime, priority;
getline(ss, value, ':'); arrivalTime = stoi(value);
getline(ss, value, ':'); burstTime = stoi(value);
getline(ss, value, ':'); priority = stoi(value);
insertProcess(head, id++, arrivalTime, burstTime, priority);
}
inFile.close();

// Clear output file for a fresh run (only on the first algorithm
call)
static bool firstRun = true;
if (firstRun) {
ofstream outFile(outputFile, ios::trunc); // Clear file content
if (!outFile) {
cerr << "Error: Could not reset output file." << endl;
return;
}
outFile.close();
firstRun = false;
}

switch (algorithm) {
case 1: sjfPreemptive(head); break;
case 2: roundRobin(head, timeQuantum); break;
case 3: sjfNonPreemptive(head); break;
case 4: priorityPreemptive(head); break;
case 5: priorityNonPreemptive(head); break;
case 6: firstComeFirstServe(head); break;
default:
cerr << "Invalid algorithm choice." << endl;
return;
}

// Write results for the current algorithm (using the algorithm


number)
Results(head, outputFile, algorithm);

// Cleanup the linked list to prevent memory leaks


while (head) {
Process* temp = head;
head = head->next;
delete temp;
}
}

void displayUsage() {
cout << "Usage: ./scheduler -t <time_quantum> -f <input_file> -o
<output_file>\n";
cout << " -t <time_quantum> Specify the time quantum for Round
Robin scheduling.\n";
cout << " -f <input_file> Specify the input file containing
process data.\n";
cout << " -o <output_file> Specify the output file to write
results.\n";
exit(EXIT_FAILURE);
}

int main(int argc, char* argv[]) {


int timeQuantum = -1;
string inputFile, outputFile;

// Parse command-line arguments


int opt;
while ((opt = getopt(argc, argv, "t:f:o:")) != -1) {
switch (opt) {
case 't': // Time quantum
timeQuantum = atoi(optarg);
if (timeQuantum <= 0) {
cerr << "Error: Time quantum must be a positive
integer.\n";
displayUsage();
return 1; // Exit after showing usage
}
break;
case 'f': // Input file
inputFile = optarg;
break;
case 'o': // Output file
outputFile = optarg;
break;
default: // Invalid argument
cerr << "Error: Invalid argument.\n";
displayUsage();
return 1; // Exit after showing usage
}
}

// Validate that all arguments are provided


if (inputFile.empty() || outputFile.empty()) {
cerr << "Error: Missing required arguments.\n";
displayUsage();
return 1; // Exit after showing usage
}

cout << "Time Quantum: " << (timeQuantum > 0 ?


to_string(timeQuantum) : "N/A") << "\n";
cout << "Input File: " << inputFile << "\n";
cout << "Output File: " << outputFile << "\n";

// Run all cpu scheduling algorithms


for (int algorithm = 1; algorithm <= 6; ++algorithm) {
if (algorithm == 2 && timeQuantum == -1) { // Round Robin
requires a time quantum
cerr << "Error: Time quantum is required for Round Robin
scheduling.\n";
return 1;
}
processFile(inputFile, outputFile, algorithm, timeQuantum);
}

cout << "Scheduling results have been written to '" << outputFile
<< "' successfully.\n";
return 0;
}

Here’s a simple explanation of the six CPU scheduling algorithms you’ve mentioned:

1. SJF (Shortest Job First) Non-Preemptive

 What it does: The CPU selects the process with the shortest burst time and
completes it before moving to the next process.
 Key Point: Once a process starts, it cannot be interrupted even if a shorter job
arrives.
 Analogy: Imagine a line at a printer. If you have a 1-page print job and someone else
has a 10-page print job, your print job is completed first, no matter when other jobs
arrive.

2. SJF (Shortest Job First) Preemptive

 What it does: The CPU selects the process with the shortest burst time. If a new
process with a shorter burst time arrives, the CPU switches to it immediately.
 Key Point: The current process can be interrupted if a shorter one arrives.
 Analogy: Imagine you're assembling sandwiches in a restaurant. If a customer orders
a simple sandwich, you’ll drop your current complex order to quickly finish the
simpler one first.

3. SRTF (Shortest Remaining Time First)

 What it does: A special case of SJF Preemptive, where the CPU always chooses the
process with the least remaining burst time.
 Key Point: The decision considers how much time a process has left, not the total
burst time.
 Analogy: If you’re cleaning up multiple tasks and a 5-minute task is halfway done,
you'll finish it before starting a new 10-minute task, even if the new task seems
shorter.

4. Round Robin (RR)

 What it does: Each process gets a fixed time slice (quantum). If it doesn’t finish, it
moves to the end of the queue, and the next process gets its turn.
 Key Point: Fair and time-shared, but processes might take longer to finish.
 Analogy: Imagine a teacher giving every student 5 minutes to speak in a debate, then
moving to the next student. If someone’s time runs out, they wait for the next round.

5. Priority Scheduling Non-Preemptive

 What it does: The CPU selects the process with the highest priority and completes it
before moving to the next.
 Key Point: Processes cannot interrupt each other; once started, a process finishes.
 Analogy: At an airport, VIPs are served first regardless of when others arrived, but
once a VIP is being served, no one else can interrupt.
6. Priority Scheduling Preemptive

 What it does: The CPU selects the process with the highest priority. If a new
process with a higher priority arrives, it interrupts the current one.
 Key Point: Current processes can be stopped mid-execution for higher-priority tasks.
 Analogy: If a VIP arrives at an airport while another is being served, the staff pauses
the current service to immediately attend to the new VIP.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy