static void Main(string[] args) { Console.WriteLine("Process Scheduling Simulator"); Console.WriteLine("Kevin Vinh Nguyen"); Console.WriteLine("CSC 4320 - Operating Systems"); Console.WriteLine("Chad Frederick"); Console.WriteLine("--------------------"); //take in input CSV file //format: priority, submission time, cpu burst time, IO burst time, CPU, IO? //number of rows is number of processes (profiles) Console.WriteLine("\nPlease enter path for CSV CPU profile sample:"); string path = Console.ReadLine(); ProcessProfiles pp = new ProcessProfiles(path); Processor CPU; Console.WriteLine("\n"); //simulate running the following scheduling algorithms //FCFS CPU = new Processor(pp); CPU.runFCFS(); Console.WriteLine(CPU.targetProfile); //SJF CPU = new Processor(pp); CPU.runSJF(); Console.WriteLine(CPU.targetProfile); //Priority First CPU = new Processor(pp); CPU.runPF(); Console.WriteLine(CPU.targetProfile); //Round Robin CPU = new Processor(pp); CPU.runRR(); Console.WriteLine(CPU.targetProfile); Console.WriteLine("\nSimulation complete. Press any key to exit..."); //prevent the console from closing before output can be read Console.ReadKey(); }
//RR - Round Robin public void runRR() { //localized instance of metrics //waiting time is defined as time spent waiting to begin the process List <int> waitTimes = new List <int>(); //turnaround time is defined as time spent waiting for the process to complete List <int> turnAroundTimes = new List <int>(); //copy of the profile ProcessProfiles ppsCopy = targetProfile; //define ready queue List <ProcessProfile> readyQueue = new List <ProcessProfile>(); //define completed list List <ProcessProfile> completedL = new List <ProcessProfile>(); //Console.WriteLine("\n" + "CYCLE | PROCESS | CPU"); //calculate runtimer int runtimeMax = calcRunTime(); int runtimeCount = 0; //ROUNDROBIN //round robin index int rrIndex = 0; //conditions to finish running: timer reaches upper maximum runtime //each loop cycle counts as 1 CPU burst cycle while (runtimeCount <= runtimeMax) { //TIME INSERTION CHECK //check if processes can be slipped into the process queue //condition is that their time must be equal to the index time pased foreach (ProcessProfile p in ppsCopy.listOfProfiles) { //if the insertion time matches the insertion time of the process in check if (runtimeCount == p.SubmissionTime) { //then add that process into the ready queue readyQueue.Add(p); // waitTimes.Add(runtimeCount); } } //PROCESS THE PROCESS PER TIME UNIT //process processes in the ready queue if (readyQueue.Count != 0) { //process takes a step closer to completion try { //process the upcoming redrobin process readyQueue[rrIndex].CPUBurstCount++; //VERBOSE //Console.WriteLine("Red Robin index: " + rrIndex); //printClock(runtimeCount, readyQueue[rrIndex], runtimeMax); } catch { //in case the rrindex oversteps the number of elements in the ready queue } //increment or reset the roundrobin counter if (((rrIndex + 1) == readyQueue.Count) || (rrIndex == readyQueue.Count)) { //if the index is at the max of the queue's contents, reset the queue. rrIndex = 0; } else { //otherwise, increment it by 1 rrIndex++; } } //MOVE COMPLETED PROCESSES INTO COMPLETED PROCESSES QUEUE for (int i = readyQueue.Count - 1; i >= 0; i--) { if (readyQueue[i].CPUBurstCount == readyQueue[i].CPUBurstTime) { //remove the process from the ready queue and move it into the completed list //note the process complete order and increment the counter completeCounter++; readyQueue[i].completeOrder = completeCounter; completedL.Add(readyQueue[i]); readyQueue.Remove(readyQueue[i]); //add a turnaround time value for the completed process turnAroundTimes.Add(runtimeCount); } } //increment the runtime clock runtimeCount++; } Console.WriteLine("======== RORO Metrics ========"); Console.WriteLine("Calculated max runtime is: " + runtimeMax); Console.WriteLine("Average Waiting Time: " + average(waitTimes) + " bursts."); Console.WriteLine("Average Turnaround Time: " + average(turnAroundTimes) + " bursts.\n"); }
//FCFS - First Come First Serve public void runFCFS() { //localized instance of metrics //waiting time is defined as time spent waiting to begin the process List <int> waitTimes = new List <int>(); //turnaround time is defined as time spent waiting for the process to complete List <int> turnAroundTimes = new List <int>(); //copy of the profile ProcessProfiles ppsCopy = targetProfile; //define ready queue List <ProcessProfile> readyQueue = new List <ProcessProfile>(); //define completed list List <ProcessProfile> completedL = new List <ProcessProfile>(); //VERBOSE //Console.WriteLine("\n" + "CYCLE | PROCESS | CPU//"); //calculate runtimer int runtimeMax = calcRunTime(); int runtimeCount = 0; //conditions to finish running: timer reaches upper maximum runtime //each loop cycle counts as 1 CPU burst cycle while (runtimeCount <= runtimeMax) { //TIME INSERTION CHECK //check if processes can be slipped into the process queue //condition is that their time must be equal to the index time pased foreach (ProcessProfile p in ppsCopy.listOfProfiles) { //if the insertion time matches the insertion time of the process in check if (runtimeCount == p.SubmissionTime) { //then add that process into the ready queue readyQueue.Add(p); // waitTimes.Add(runtimeCount); } } //PROCESS THE PROCESS PER TIME UNIT //process processes in the ready queue if (readyQueue.Count != 0) { //process takes a step closer to completion readyQueue[0].CPUBurstCount++; //VERBOSE //printClock(runtimeCount, readyQueue[0], runtimeMax); } //MOVE COMPLETED PROCESSES INTO COMPLETED PROCESSES QUEUE //foreach left for thinking reference- will error out as the collection will be modified post enumeration of the foreach loop; see alternative solution in form of reversed for loop /*foreach (ProcessProfile p in readyQueue) * { * //checks every process inside the ready queue: * //if the process allotted burst time has matched the passed burst time, it is considered complete. * if (p.CPUBurstCount == p.CPUBurstTime) * { * //remove the process from the ready queue and move it into the completed list * completedL.Add(p); * readyQueue.Remove(p); * } * }*/ for (int i = readyQueue.Count - 1; i >= 0; i--) { if (readyQueue[i].CPUBurstCount == readyQueue[i].CPUBurstTime) { completeCounter++; readyQueue[i].completeOrder = completeCounter; //remove the process from the ready queue and move it into the completed list completedL.Add(readyQueue[i]); readyQueue.Remove(readyQueue[i]); //add a turnaround time value for the completed process turnAroundTimes.Add(runtimeCount); } } //increment the runtime clock runtimeCount++; } Console.WriteLine("======== FCFS Metrics ========"); Console.WriteLine("Calculated max runtime is: " + runtimeMax); Console.WriteLine("Average Waiting Time: " + average(waitTimes) + " bursts."); Console.WriteLine("Average Turnaround Time: " + average(turnAroundTimes) + " bursts.\n"); }
//PF - Priority First public void runPF() { //localized instance of metrics //waiting time is defined as time spent waiting to begin the process List <int> waitTimes = new List <int>(); //turnaround time is defined as time spent waiting for the process to complete List <int> turnAroundTimes = new List <int>(); //copy of the profile ProcessProfiles ppsCopy = targetProfile; //define ready queue List <ProcessProfile> readyQueue = new List <ProcessProfile>(); //define completed list List <ProcessProfile> completedL = new List <ProcessProfile>(); //VERBOSE //Console.WriteLine("\n" + "CYCLE | PROCESS | CPU//"); //calculate runtimer int runtimeMax = calcRunTime(); int runtimeCount = 0; //HP int mostImportant = -1; //-1 means no jobs in the queue yet //conditions to finish running: timer reaches upper maximum runtime //each loop cycle counts as 1 CPU burst cycle while (runtimeCount <= runtimeMax) { //TIME INSERTION CHECK //check if processes can be slipped into the process queue //condition is that their time must be equal to the index time pased foreach (ProcessProfile p in ppsCopy.listOfProfiles) { //if the insertion time matches the insertion time of the process in check if (runtimeCount == p.SubmissionTime) { //INSERT PROCESS INTO THE READY QUEUE Boolean canCheck = false; try { if (p.Priority < readyQueue[mostImportant].Priority) { canCheck = true; } } catch (Exception e) { canCheck = false; } //if there are no processes if (mostImportant == -1) { //then just drop it in readyQueue.Add(p); mostImportant = 0; } //if the process to be inserted is shorter than the one currently in the front //check priority else if (mostImportant <= 0 && canCheck) { readyQueue.Insert(mostImportant - 1, p); mostImportant = readyQueue.IndexOf(p); } //if the process is longer than the one currently in the front else if (!canCheck /*p.Priority >= readyQueue[mostImportant].Priority*/) { //insert it afterwards readyQueue.Insert(mostImportant, p); //and tell the shortestJob index where the shortest job is mostImportant = readyQueue.IndexOf(p); } //increment the runtime counter waitTimes.Add(runtimeCount); } } //PROCESS THE PROCESS PER TIME UNIT //process processes in the ready queue if (readyQueue.Count != 0) { //process takes a step closer to completion readyQueue[0].CPUBurstCount++; //VERBOSE //printClock(runtimeCount, readyQueue[0], runtimeMax); } //MOVE COMPLETED PROCESSES INTO COMPLETED PROCESSES QUEUE for (int i = readyQueue.Count - 1; i >= 0; i--) { if (readyQueue[i].CPUBurstCount >= readyQueue[i].CPUBurstTime) { completeCounter++; readyQueue[i].completeOrder = completeCounter; //remove the process from the ready queue and move it into the completed list completedL.Add(readyQueue[i]); readyQueue.Remove(readyQueue[i]); //add a turnaround time value for the completed process turnAroundTimes.Add(runtimeCount); //Console.WriteLine("I'm checking!"); } } //increment the runtime clock runtimeCount++; } Console.WriteLine("======== PF Metrics ========"); Console.WriteLine("Calculated max runtime is: " + runtimeMax); Console.WriteLine("Average Waiting Time: " + average(waitTimes) + " bursts."); Console.WriteLine("Average Turnaround Time: " + average(turnAroundTimes) + " bursts.\n"); }
//a processor needs processes to actually process, so it will take a ProcessProfiles container as a constructor input. public Processor(ProcessProfiles pps) { targetProfile = pps; }