-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFBV.java
More file actions
258 lines (235 loc) · 11 KB
/
Copy pathFBV.java
File metadata and controls
258 lines (235 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
/* COMP2240 Assignment 1
* File: FBV.java
* Author: Nicholas Steuart c3330826
* Date Created: 12/8/24
* Date Last Modified: 5/9/24
* Description: Provides functionality of a Standard multi-level (3 levels) Feedback Scheduling Algorithm which uses Round Robin for it's
* lowest priority queue
*/
// PACKAGES //
import java.util.ArrayList;
public class FBV extends Scheduler
{
// CLASS VARIABLES //
private ArrayList<Process> enterQueue; //Stores Process objects that will be run in the CPU scheduling simulation
private ArrayList<Process> highPriorityQueue = new ArrayList<Process>(); //Stores ready Process objects with the highest priority (Priority = 1)
private ArrayList<Process> medPriorityQueue = new ArrayList<Process>(); //Stores ready Process objects with the second highest priority (Priority = 2)
private ArrayList<Process> lowPriorityQueue = new ArrayList<Process>(); //Stores ready Process objects with the lowest priority (Priority = 3)
private ArrayList<Process> finishedQueue = new ArrayList<Process>(); //Stores Process objects that have finished executing
private final int DISPATCHER; //Time taken for the dispatcher to choose the next process to run
private int timer = 0; //Time units of the simulation
private String name = "FBV"; //Name of the scheduling algorithm
private boolean[] visited; //Flags whether a Process object in the enterQueue has been admitted to the readyQueue or not
// CONSTRUCTORS //
//PRE-CONDITION: No PRE-CONDITION
//POST-CONDITION: Class variables enterQueue, DISPATCHER and visited instantiated with default values
public FBV()
{
enterQueue = new ArrayList<Process>();
DISPATCHER = 0;
visited = new boolean[0];
}
//PRE-CONDITION:
//Parameter enterQueue must not be null and must contain at least one Process object
//Parameter DISPATCHER must be zero or a positive integer
//POST-CONDITION:
//Specialised Constructor instantiated with parameters enterQueue and DISPATCHER mutating their respective Class variables
//and Class variable visited instantiated with a flag for each Process object in enterQueue
public FBV(ArrayList<Process> enterQueue, int dispatcher)
{
this.enterQueue = enterQueue;
this.DISPATCHER = dispatcher;
visited = new boolean[enterQueue.size()];
}
// METHODS //
//PRE-CONDITION: FBV constructor instantiated
//POST-CONDITION: Returns the next Process object in the readyQueue to run based on what the next highest priority Process is
@Override
public Process dispatch()
{
Process nextDispatch = new Process();
if(!highPriorityQueue.isEmpty()) //There is atleast 1 high priority ready Process object
{
nextDispatch = highPriorityQueue.get(0);
}
else if(!medPriorityQueue.isEmpty()) //There is atleast 1 medium priority ready Process object and no high priority Process object ready
{
nextDispatch = medPriorityQueue.get(0);
}
else if(!lowPriorityQueue.isEmpty()) //There is atleast 1 low priority ready Process object and no high or medium priority Process object ready
{
nextDispatch = lowPriorityQueue.get(0);
}
timer += DISPATCHER; //Increment time taken to dispatch
//Log the next running Process object's entry time in the CPU and it's ID
String dispatchLog = "T" + timer + ": " + nextDispatch.getPID();
dispatchLogs.add(dispatchLog);
return nextDispatch;
}
//PRE-CONDITION: FBV Constructor instantiated
//POST-CONDITION: Process objects in the enterQueue that are ready to run are added to the highPriorityQueue
@Override
public void admit()
{
for(int i = 0; i < enterQueue.size(); i++)
{
if(enterQueue.get(i).getArrTime() <= timer && !visited[i])
{
highPriorityQueue.add(enterQueue.get(i));
visited[i] = true;
}
}
}
//PRE-CONDITION: FBV Constructor instantiated
//POST-CONDITION:
//All Process object's in enterQueue run through the FBV CPU scheduling algorithm
//finishedQueue populated with every enterQueue Process object
@Override
public void run()
{
//Runs until every Process object in enterQueue has finished executing
while(!highPriorityQueue.isEmpty() || !medPriorityQueue.isEmpty() || !lowPriorityQueue.isEmpty() || enterQueue.size() > finishedQueue.size())
{
admit(); //Admit Process objects that are ready from the enterQueue
Process runningProcess = dispatch(); //Dispatch the next Process object to run
if(runningProcess.getPriority() == 1) //IF running Process object is a high priority process...
{
executeProcess(runningProcess, 2); //Execute running Process object for time slice of 2 time units
}
else if(runningProcess.getPriority() == 2) //IF running Process object is a medium priority process...
{
executeProcess(runningProcess, 4); //Execute running Process object for time slice of 4 time units
}
else if(runningProcess.getPriority() == 3) //IF running Process object is a low priority process...
{
executeRoundRobin(runningProcess, 4); //Execute running Process object for a time slice of 4 time units in a Round Robin fashion
}
}
}
//PRE-CONDITION:
//FBV Constructor instantiated
//runningProcess not equal to null
//timeSlice must be a non-negative integer
//POST-CONDITION:
//runningProcess has executed for its allocated timeSlice, or
//finished executing during it's timeSlice and populated the finishedQueue
public void executeProcess(Process runningProcess, int timeSlice)
{
//IF runningProcess will not finish executing after receiving it's timeSlice...
if(runningProcess.getTimeRemaining() > timeSlice)
{
//Execute runningProcess for allocated timeSlice
runningProcess.setTimeRemaining(runningProcess.getTimeRemaining() - timeSlice);
for(int i = 0; i < timeSlice; i++)
{
timer++;
admit(); //Must be checked to maintain order of new Process objects becoming ready during the running Process timeSlice
}
//After the runningProcess receives it's timeSlice, Reduce it's Priority by one and place it in it's new priority queue
if(runningProcess.getPriority() == 1)
{
runningProcess.setPriority(2);
medPriorityQueue.add(runningProcess);
highPriorityQueue.remove(runningProcess);
}
else if(runningProcess.getPriority() == 2)
{
runningProcess.setPriority(3);
lowPriorityQueue.add(runningProcess);
medPriorityQueue.remove(runningProcess);
}
}
else //IF runningProcess will finish during it's timeSlice...
{
for(int i = 0; i < runningProcess.getTimeRemaining(); i++)
{
timer++;
admit(); //Same check as line 140
}
//Calculate turnaround time and wait time of the Process object
runningProcess.setTurnTime(timer - runningProcess.getArrTime());
runningProcess.setWaitTime(timer - (runningProcess.getArrTime() + runningProcess.getSrvTime()));
//Remove runningProcess from it's particular priority queue
if(runningProcess.getPriority() == 1)
{
finishedQueue.add(runningProcess);
highPriorityQueue.remove(runningProcess);
}
else if(runningProcess.getPriority() == 2)
{
finishedQueue.add(runningProcess);
medPriorityQueue.remove(runningProcess);
}
}
}
//PRE-CONDITION:
//FBV Constructor instantiated
//runningProcess not equal to null
//timeSlice must be a non-negative integer
//POST-CONDITION:
//runningProcess has executed for its allocated timeSlice and added to the back of the low priority queue in a Round Robin fashion, or
//runningProcess has executed for its allocated timeSlice and has been re-added to the high priority queue due to it starving in the low priority queue for more than 16 time units, or
//finished executing during it's timeSlice and populated the finishedQueue
public void executeRoundRobin(Process runningProcess, int timeSlice)
{
//Assign runningProcess to the first Process object in the low Priority Queue
runningProcess = lowPriorityQueue.get(0);
//Increment runningProcess starvationTime by the timeSlice
runningProcess.setStarvationTime(runningProcess.getStarvationTime() + timeSlice);
//IF runningProcess will not finish executing after receiving it's timeSlice...
if(runningProcess.getTimeRemaining() > timeSlice)
{
//Execute runningProcess for allocated timeSlice
runningProcess.setTimeRemaining(runningProcess.getTimeRemaining() - timeSlice);
for(int i = 0; i < timeSlice; i++)
{
timer++;
admit(); //Same check as line 140
}
//Priority Boost Process to Highest Priority Queue if it has spent more than 16 time units in the Low Priority Queue
if(runningProcess.getStarvationTime() > 16)
{
runningProcess.setPriority(1);
//Update priority queues
highPriorityQueue.add(runningProcess);
lowPriorityQueue.remove(runningProcess);
}
}
else //IF runningProcess will finish during it's timeSlice...
{
for(int i = 0; i < timeSlice; i++)
{
timer++;
admit(); //Same check as line 140
}
//Calculate turnaround time and wait time of the Process object
runningProcess.setTurnTime(timer - runningProcess.getArrTime());
runningProcess.setWaitTime(timer - (runningProcess.getArrTime() + runningProcess.getSrvTime()));
//Remove runningProcess from the low priority quuee
finishedQueue.add(runningProcess);
lowPriorityQueue.remove(runningProcess);
}
}
// ACCESSORS //
//PRE-CONDITION: FBV Constructor instantiated
//POST-CONDITION: Class variable name returned
@Override
public String getName()
{
return name;
}
//PRE-CONDITION: FBV Constructor instantiated
//POST-CONDITION: Class variable enterQueue returned
@Override
public ArrayList<Process> getEnterQueue()
{
return enterQueue;
}
//PRE-CONDITION: FBV Constructor instantiated
//POST-CONDITION: Parent Class variable dispatchLogs returned
@Override
public ArrayList<String> getDispatchLogs()
{
return dispatchLogs;
}
}