321 lines
13 KiB
Java
321 lines
13 KiB
Java
/**
|
||
* @author Tawfik Yasser
|
||
* @since 4-2021
|
||
* */
|
||
// Program imports below
|
||
import java.util.ArrayList;
|
||
import java.util.Scanner;
|
||
// The following class to represent the process
|
||
// ** In future i will fix the name "process" to "Process"
|
||
class process {
|
||
String name;
|
||
int burset_time;
|
||
int arrive_time;
|
||
int waiting_time;
|
||
int turn_round_time;
|
||
int temp_time;
|
||
int queueNumber;
|
||
|
||
//Priority Algorithm
|
||
private int processID;
|
||
private int priority;
|
||
|
||
public process() {
|
||
this.processID = 0;
|
||
this.priority = 0;
|
||
this.arrive_time = 0;
|
||
this.burset_time = 0;
|
||
}
|
||
|
||
public process(String name, int burset_time, int arrive_time) {
|
||
this.arrive_time = arrive_time;
|
||
this.burset_time = burset_time;
|
||
this.name = name;
|
||
this.temp_time = burset_time;
|
||
}
|
||
|
||
public process(String name, int burset_time, int arrive_time, int queueNumber) {
|
||
this.name = name;
|
||
this.burset_time = burset_time;
|
||
this.arrive_time = arrive_time;
|
||
this.queueNumber = queueNumber;
|
||
}
|
||
|
||
public process(int processID, int priority, int arrivingTime, int burstTime) {
|
||
this.processID = processID;
|
||
this.priority = priority;
|
||
this.arrive_time = arrivingTime;
|
||
this.burset_time = burstTime;
|
||
}
|
||
|
||
public int getProcessID() {
|
||
return processID;
|
||
}
|
||
|
||
public void setProcessID(int processID) {
|
||
this.processID = processID;
|
||
}
|
||
|
||
public int getPriority() {
|
||
return priority;
|
||
}
|
||
|
||
public void setPriority(int priority) {
|
||
this.priority = priority;
|
||
}
|
||
|
||
public void setWaiting_time(int waiting_time) {
|
||
this.waiting_time = waiting_time;
|
||
}
|
||
|
||
public void setTurn_round_time(int turn_round_time) {
|
||
this.turn_round_time = turn_round_time;
|
||
}
|
||
|
||
public void setTemp_burset_time(int temp_burset_time) {
|
||
this.temp_time = temp_burset_time;
|
||
}
|
||
|
||
public int getWaiting_time() {
|
||
return waiting_time;
|
||
}
|
||
|
||
public int getTurn_round_time() {
|
||
return turn_round_time;
|
||
}
|
||
|
||
|
||
public String getName() {
|
||
return name;
|
||
}
|
||
|
||
public void setName(String name) {
|
||
this.name = name;
|
||
}
|
||
|
||
public void setBurset_time(int burset_time) {
|
||
this.burset_time = burset_time;
|
||
}
|
||
|
||
public void setArrive_time(int arrive_time) {
|
||
this.arrive_time = arrive_time;
|
||
}
|
||
|
||
public int getBurset_time() {
|
||
return burset_time;
|
||
}
|
||
|
||
public int getTemp_burset_time() {
|
||
return temp_time;
|
||
}
|
||
|
||
public int getArrive_time() {
|
||
return arrive_time;
|
||
}
|
||
|
||
public int getQueueNumber() {
|
||
return queueNumber;
|
||
}
|
||
|
||
public void setQueueNumber(int queueNumber) {
|
||
this.queueNumber = queueNumber;
|
||
}
|
||
|
||
public void reduceTime(int time) {
|
||
if(burset_time >= time)
|
||
burset_time = burset_time - time;
|
||
}
|
||
}
|
||
|
||
// ****************** The following class to start the MLQ Algorithm, Called from the main
|
||
class MultiLevelQueueScheduling {
|
||
public MultiLevelQueueScheduling() {
|
||
|
||
}
|
||
|
||
public void MLQ(int number,process[] processes,int quantum){
|
||
float totalwt = 0, totaltat = 0;
|
||
int[] completionTime = new int[number], waitingTime = new int[number], turnaroundTime = new int[number];
|
||
ArrayList<Integer> RRQueue = new ArrayList<Integer>(); // Queue to store Round Robin Processes Indexes
|
||
ArrayList<Integer> FCFSQueue = new ArrayList<Integer>(); // Queue to store FCFS Processes Indexes
|
||
|
||
for (int i = 0; i < number; i++) {
|
||
if (processes[i].getQueueNumber() == 1) {
|
||
RRQueue.add(i);
|
||
}else{
|
||
FCFSQueue.add(processes[i].getQueueNumber());
|
||
}
|
||
}
|
||
|
||
int[] highPriorityProcessArray = new int[number]; // Array to work on it instead of the RRQueue
|
||
for (int i = 0; i < RRQueue.size(); i++) {
|
||
highPriorityProcessArray[i] = RRQueue.get(i);
|
||
}
|
||
|
||
int rem_bt[] = new int[RRQueue.size()]; // Array to store the burst time of each process from RRQueue and work on it.
|
||
for (int i = 0; i < RRQueue.size(); i++) {
|
||
rem_bt[i] = processes[highPriorityProcessArray[i]].getBurset_time();
|
||
}
|
||
int rem_bt_2[] = new int[FCFSQueue.size()]; // Array to store the burst time of each process from FCFSQueue and work on it.
|
||
for (int i =0;i<FCFSQueue.size();i++){
|
||
rem_bt_2[i] = processes[FCFSQueue.get(i)].getBurset_time();
|
||
}
|
||
|
||
int t = completionTime[0]; // t is the starting time of executing processes (t=0)
|
||
int flag =0;
|
||
|
||
//Starting to execute the processes
|
||
while (true) {
|
||
boolean done = true;
|
||
|
||
// Starting of executing the Round Robin Queue Processes
|
||
for (int i = 0; i < RRQueue.size(); i++)
|
||
{
|
||
//Checking if the process arrived and still has burst time
|
||
if (processes[RRQueue.get(i)].getArrive_time() <= t && rem_bt[i] > 0) {
|
||
//System.out.println("Process "+processes[RRQueue.get(i)].getName()+" Arrived Now - Time: "+t);
|
||
// Check again for burst time if still greater than 0
|
||
if (rem_bt[i] > 0) {
|
||
done = false; // Processes still working
|
||
|
||
//Checking if the process still has burst time
|
||
if (rem_bt[i] > quantum) {
|
||
System.out.println("Process "+processes[RRQueue.get(i)].getName()+" Running Now.");
|
||
// Increase the value of t of the program and shows how much time a process has been processed.
|
||
t += quantum;
|
||
// Decrease the burst_time of current process by quantum
|
||
rem_bt[i] -= quantum;
|
||
}
|
||
// If burst time is smaller than or equal to quantum. So this is the last loop this process
|
||
else {
|
||
System.out.println("Process "+processes[RRQueue.get(i)].getName()+" Running Now.");
|
||
// Increase the value of t
|
||
t = t + rem_bt[i];
|
||
completionTime[highPriorityProcessArray[i]] = t; //Calculate that process completion time.
|
||
//--> [Turnaround Time = Completion Time - Arrival Time]
|
||
turnaroundTime[highPriorityProcessArray[i]] = completionTime[highPriorityProcessArray[i]]
|
||
- processes[highPriorityProcessArray[i]].getArrive_time();//Calculate the process turnaround time
|
||
//--> [Waiting Time = Turnaround Time - Burst Time]
|
||
waitingTime[highPriorityProcessArray[i]] = turnaroundTime[highPriorityProcessArray[i]]
|
||
- processes[highPriorityProcessArray[i]].getBurset_time();//Calculating the process waiting time
|
||
// And finally that process finished it’s work so the burst time will be ZERO now.
|
||
rem_bt[i] = 0;
|
||
System.out.println("Process "+processes[RRQueue.get(i)].getName()+" Finished Work - Time: "+t);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
//Here we are check if there are another processes need to work in the second queue.
|
||
flag=0;
|
||
for(int k = 0 ; k <RRQueue.size();k++){
|
||
if(rem_bt[k] == 0 || processes[RRQueue.get(k)].getArrive_time() > t){
|
||
flag++;
|
||
}
|
||
}
|
||
}
|
||
//Position a variable to store the position of the processes from the second queue.
|
||
int position =0;
|
||
if(flag==RRQueue.size()){
|
||
//Looping on the second queue and execute the processes until the first queue filled again.
|
||
for (int j = 0; j < FCFSQueue.size(); j++) {
|
||
String fl = " ";//Flag
|
||
do{
|
||
//System.out.println("Process "+processes[FCFSQueue.get(j)].getName()+" Arrived Now - Time: "+t);
|
||
//The following loop to get the process position.
|
||
for(int y =0;y<number;y++){
|
||
if(processes[FCFSQueue.get(j)].getName().equals(processes[y].getName())){
|
||
position = y;
|
||
break;
|
||
}
|
||
}
|
||
//Calculating the Completion time and turnaround time and waiting time for each process in FCFSQueue.
|
||
completionTime[position] = t;
|
||
turnaroundTime[position] = completionTime[position] - processes[position].getArrive_time();
|
||
waitingTime[position] = turnaroundTime[position] - processes[position].getBurset_time();
|
||
if(rem_bt_2[j]==0){
|
||
System.out.println("Process "+processes[FCFSQueue.get(j)].getName()+" Finished Work - Time: "+t);
|
||
}else {
|
||
System.out.println("Process "+processes[FCFSQueue.get(j)].getName()+" Running Now.");
|
||
}
|
||
t++;//Increase the time.
|
||
rem_bt_2[j] -= 1;//Decrease the process burst time.
|
||
//Every unit of time checking if there are new process in the first queue.
|
||
//So we should stop the FCFS queue execution and go back to the first queue because the first queue has higher priority.
|
||
for(int h = 0 ; h<RRQueue.size();h++){
|
||
if(t == processes[RRQueue.get(h)].getArrive_time()){
|
||
System.out.println("Process "+processes[FCFSQueue.get(j)].getName()+" Blocked Temporary (X) at Time: "+t);
|
||
fl = "out";
|
||
break;
|
||
}
|
||
}
|
||
|
||
}while(fl.equals(" ") && rem_bt_2[j] >0);
|
||
if(!fl.equals(" ")){
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// If all processes are done their execution.
|
||
if (done == true)
|
||
break;
|
||
}
|
||
|
||
|
||
//Printing the final results of execution.
|
||
System.out.println("\nProcess Name\t\t Queue Number \tBurst Time \tCompletion Time \tWaiting Time \tTurnaround Time");
|
||
for (int i = 0; i < number; i++) {
|
||
System.out.println("\n\t" + processes[i].getName() + "\t\t\t\t\t" + processes[i].getQueueNumber() + "\t\t\t\t" + processes[i].getBurset_time() + "\t\t\t\t" + completionTime[i] + "\t\t\t\t" + waitingTime[i] + "\t\t\t\t" + turnaroundTime[i]);
|
||
}
|
||
|
||
//Calculating the AVG Waiting Time and Turnaround Time
|
||
for (int i = 0; i < number; i++) {
|
||
totalwt += waitingTime[i];
|
||
totaltat += turnaroundTime[i];
|
||
}
|
||
System.out.println("\n" + "Average Waiting Time is: " + totalwt / number);
|
||
System.out.println("Average Turnaround Time is : " + totaltat / number);
|
||
}
|
||
}
|
||
|
||
// The following is the Main function to run the program
|
||
|
||
public class Main {
|
||
public static void main(String[] args) {
|
||
System.out.print("\n");
|
||
System.out.println("Welcome to the CPU Scheduler Simulator >>>>> (OS)");
|
||
System.out.println("-------------------------------------------------");
|
||
System.out.println("Running the Multi-Level Queue Scheduling Algorithm");
|
||
multiLevelScheduling();
|
||
}
|
||
|
||
public static void multiLevelScheduling() {
|
||
int quantum = 0;
|
||
int number;
|
||
System.out.println("Enter number of processes: ");
|
||
Scanner scanner = new Scanner(System.in);
|
||
number = scanner.nextInt();
|
||
process[] processes = new process[number];
|
||
|
||
for (int i = 0; i < number; i++) {
|
||
|
||
System.out.println("Enter the name of process " + (i + 1) + " : ");
|
||
String name = scanner.next();
|
||
System.out.println("Enter the arrival time of process " + (i + 1) + " : ");
|
||
int arrival = scanner.nextInt();
|
||
System.out.println("Enter the burst time of process " + (i + 1) + " : ");
|
||
int burst = scanner.nextInt();
|
||
System.out.println("Enter the queue number of process " + (i + 1) + " : ");
|
||
int qNumber = scanner.nextInt();
|
||
|
||
process process = new process(name, burst, arrival, qNumber);
|
||
processes[i] = process;
|
||
}
|
||
System.out.println("Enter the quantum time: ");
|
||
quantum = scanner.nextInt();
|
||
MultiLevelQueueScheduling multiLevelQueueScheduling = new MultiLevelQueueScheduling();
|
||
multiLevelQueueScheduling.MLQ(number,processes,quantum);
|
||
|
||
}
|
||
} |