├── README.md
├── app.js
├── index.html
└── style.css
/README.md:
--------------------------------------------------------------------------------
1 | # cpu-scheduling-sim
2 | CPU Scheduling Simulator
3 |
4 | This application is built for my OS mini project. I'll continue developing this application which will include bug fixes and new features.
5 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | $(document).ready(
2 | function(){
3 |
4 | $(".form-group-time-quantum").hide();
5 |
6 | // Show hide RR time quantum
7 | $('#algorithmSelector').on('change', function(){
8 | if(this.value === 'optRR') {
9 | $(".form-group-time-quantum").show(1000);
10 | } else {
11 | $(".form-group-time-quantum").hide(1000);
12 | }
13 | });
14 |
15 |
16 | var processList = [];
17 |
18 | $('#btnAddProcess').on('click', function(){
19 | var processID = $('#processID');
20 | var arrivalTime = $('#arrivalTime');
21 | var burstTime = $('#burstTime');
22 |
23 | if(processID.val() === '' || arrivalTime.val() === '' || burstTime.val() === ''){
24 | processID.addClass('is-invalid');
25 | arrivalTime.addClass('is-invalid');
26 | burstTime.addClass('is-invalid');
27 | return;
28 | }
29 |
30 | var process = {
31 | processID: parseInt(processID.val(), 10),
32 | arrivalTime: parseInt(arrivalTime.val(), 10),
33 | burstTime: parseInt(burstTime.val(), 10)
34 | }
35 |
36 | processList.push(process);
37 |
38 | $('#tblProcessList > tbody:last-child').append(
39 | `
40 | ${processID.val()} |
41 | ${arrivalTime.val()} |
42 | ${burstTime.val()} |
43 |
`
44 | );
45 |
46 | processID.val('');
47 | arrivalTime.val('');
48 | burstTime.val('');
49 | });
50 |
51 | $('#btnCalculate').on('click', function(){
52 |
53 | if (processList.length == 0) {
54 | alert('Please insert some processes');
55 | return;
56 | }
57 |
58 | var selectedAlgo = $('#algorithmSelector').children('option:selected').val();
59 |
60 | if (selectedAlgo === 'optFCFS') {
61 | firstComeFirstServed();
62 | }
63 |
64 | if (selectedAlgo === 'optSJF') {
65 | shortestJobFirst();
66 | }
67 |
68 | if (selectedAlgo === 'optSRTF') {
69 | shortestRemainingTimeFirst();
70 | }
71 |
72 | if (selectedAlgo === 'optRR') {
73 | roundRobin();
74 | }
75 | });
76 |
77 | function firstComeFirstServed(){
78 | var time = 0;
79 | var queue = [];
80 | var completedList = [];
81 |
82 | while (processList.length > 0 || queue.length > 0) {
83 | while (queue.length == 0) {
84 | time++;
85 | addToQueue();
86 | }
87 |
88 | // Dequeue from queue and run the process.
89 | process = queue.shift();
90 | for(var i = 0; i < process.burstTime; i++){
91 | time++
92 | addToQueue();
93 | }
94 | process.completedTime = time;
95 | process.turnAroundTime = process.completedTime - process.arrivalTime;
96 | process.waitingTime = process.turnAroundTime - process.burstTime;
97 | completedList.push(process);
98 | }
99 |
100 | function addToQueue() {
101 | for(var i = 0; i < processList.length; i++) {
102 | if(time >= processList[i].arrivalTime) {
103 | var process = {
104 | processID: processList[i].processID,
105 | arrivalTime: processList[i].arrivalTime,
106 | burstTime: processList[i].burstTime
107 | }
108 | processList.splice(i, 1);
109 | queue.push(process);
110 | }
111 | }
112 | }
113 |
114 | // Bind table data
115 | $.each(completedList, function(key, process){
116 | $('#tblResults > tbody:last-child').append(
117 | `
118 | ${process.processID} |
119 | ${process.arrivalTime} |
120 | ${process.burstTime} |
121 | ${process.completedTime} |
122 | ${process.waitingTime} |
123 | ${process.turnAroundTime} |
124 |
`
125 | );
126 | });
127 |
128 | // Get average
129 | var avgTurnaroundTime = 0;
130 | var avgWaitingTime = 0;
131 | var maxCompletedTime = 0;
132 |
133 | $.each(completedList, function(key, process){
134 | if (process.completedTime > maxCompletedTime) {
135 | maxCompletedTime = process.completedTime;
136 | }
137 | avgTurnaroundTime = avgTurnaroundTime + process.turnAroundTime;
138 | avgWaitingTime = avgWaitingTime + process.waitingTime;
139 | });
140 |
141 | $('#avgTurnaroundTime').val( avgTurnaroundTime / completedList.length );
142 | $('#avgWaitingTime').val( avgWaitingTime / completedList.length );
143 | $('#throughput').val(completedList.length / maxCompletedTime);
144 | }
145 |
146 | function shortestJobFirst(){
147 | var completedList = [];
148 | var time = 0;
149 | var queue = [];
150 |
151 | while (processList.length>0 || queue.length>0) {
152 | addToQueue();
153 | while (queue.length==0) {
154 | time++;
155 | addToQueue();
156 | }
157 | processToRun = selectProcess();
158 | for (var i = 0; i < processToRun.burstTime; i++) {
159 | time++;
160 | addToQueue();
161 | }
162 | processToRun.processID = processToRun.processID;
163 | processToRun.arrivalTime = processToRun.arrivalTime;
164 | processToRun.burstTime = processToRun.burstTime;
165 | processToRun.completedTime = time;
166 | processToRun.turnAroundTime = processToRun.completedTime - processToRun.arrivalTime;
167 | processToRun.waitingTime = processToRun.turnAroundTime - processToRun.burstTime;
168 | completedList.push(processToRun);
169 | }
170 | function addToQueue() {
171 | for(var i = 0; i < processList.length; i++) {
172 | if(processList[i].arrivalTime === time) {
173 | var process = {
174 | processID: processList[i].processID,
175 | arrivalTime: processList[i].arrivalTime,
176 | burstTime: processList[i].burstTime
177 | }
178 | processList.splice(i, 1);
179 | queue.push(process);
180 | }
181 | }
182 | }
183 | function selectProcess() {
184 | if (queue.length!=0) {
185 | queue.sort(function(a, b){
186 | if (a.burstTime > b.burstTime) {
187 | return 1;
188 | } else {
189 | return -1;
190 | }
191 | });
192 | }
193 | var process = queue.shift();
194 | return process;
195 | }
196 |
197 | // Bind table data
198 | $.each(completedList, function(key, process){
199 | $('#tblResults > tbody:last-child').append(
200 | `
201 | ${process.processID} |
202 | ${process.arrivalTime} |
203 | ${process.burstTime} |
204 | ${process.completedTime} |
205 | ${process.waitingTime} |
206 | ${process.turnAroundTime} |
207 |
`
208 | );
209 | });
210 |
211 | // Get average
212 | var avgTurnaroundTime = 0;
213 | var avgWaitingTime = 0;
214 | var maxCompletedTime = 0;
215 | var throughput = 0;
216 |
217 | $.each(completedList, function(key, process){
218 | if (process.completedTime > maxCompletedTime) {
219 | maxCompletedTime = process.completedTime;
220 | }
221 | avgTurnaroundTime = avgTurnaroundTime + process.turnAroundTime;
222 | avgWaitingTime = avgWaitingTime + process.waitingTime;
223 | });
224 |
225 | $('#avgTurnaroundTime').val( avgTurnaroundTime / completedList.length );
226 | $('#avgWaitingTime').val( avgWaitingTime / completedList.length );
227 | $('#throughput').val(completedList.length / maxCompletedTime);
228 | }
229 |
230 | function shortestRemainingTimeFirst() {
231 | var completedList = [];
232 | var time = 0;
233 | var queue = [];
234 |
235 | while ( processList.length>0 || queue.length>0 ) {
236 | addToQueue();
237 | while (queue.length==0) {
238 | time++;
239 | addToQueue();
240 | }
241 | selectProcessForSRTF();
242 | runSRTF();
243 | }
244 |
245 | function addToQueue() {
246 | for(var i = 0; i < processList.length; i++) {
247 | if(processList[i].arrivalTime === time) {
248 | var process = {
249 | processID: processList[i].processID,
250 | arrivalTime: processList[i].arrivalTime,
251 | burstTime: processList[i].burstTime
252 | }
253 | processList.splice(i, 1);
254 | queue.push(process);
255 | }
256 | }
257 | }
258 | function selectProcessForSRTF() {
259 | if (queue.length != 0) {
260 | queue.sort(function(a, b){
261 | if (a.burstTime > b.burstTime) {
262 | return 1;
263 | } else {
264 | return -1;
265 | }
266 | });
267 | if (queue[0].burstTime == 1) {
268 | process = queue.shift();
269 | process.completedTime = time + 1;
270 | completedList.push(process);
271 |
272 | } else if(queue[0].burstTime > 1){
273 | process = queue[0];
274 | queue[0].burstTime = process.burstTime - 1;
275 | }
276 | }
277 | }
278 | function runSRTF() {
279 | time++;
280 | addToQueue();
281 | }
282 |
283 | // Fetch table data
284 | var TableData = [];
285 | $('#tblProcessList tr').each(function(row, tr) {
286 | TableData[row] = {
287 | "processID": parseInt($(tr).find('td:eq(0)').text()),
288 | "arrivalTime": parseInt($(tr).find('td:eq(1)').text()),
289 | "burstTime": parseInt($(tr).find('td:eq(2)').text())
290 | }
291 | });
292 |
293 | // Remove header row
294 | TableData.splice(0, 1);
295 |
296 | // Reset burst time
297 | TableData.forEach(pInTable => {
298 | completedList.forEach(pInCompleted => {
299 | if (pInTable.processID == pInCompleted.processID) {
300 | pInCompleted.burstTime = pInTable.burstTime;
301 | pInCompleted.turnAroundTime = pInCompleted.completedTime - pInCompleted.arrivalTime;
302 | pInCompleted.waitingTime = pInCompleted.turnAroundTime - pInCompleted.burstTime;
303 | }
304 | });
305 | });
306 |
307 | // Bind table data
308 | $.each(completedList, function(key, process){
309 | $('#tblResults > tbody:last-child').append(
310 | `
311 | ${process.processID} |
312 | ${process.arrivalTime} |
313 | ${process.burstTime} |
314 | ${process.completedTime} |
315 | ${process.waitingTime} |
316 | ${process.turnAroundTime} |
317 |
`
318 | );
319 | });
320 |
321 | // Get average
322 | var avgTurnaroundTime = 0;
323 | var avgWaitingTime = 0;
324 | var maxCompletedTime = 0;
325 | var throughput = 0;
326 |
327 | $.each(completedList, function(key, process){
328 | if (process.completedTime > maxCompletedTime) {
329 | maxCompletedTime = process.completedTime;
330 | }
331 | avgTurnaroundTime = avgTurnaroundTime + process.turnAroundTime;
332 | avgWaitingTime = avgWaitingTime + process.waitingTime;
333 | });
334 |
335 | $('#avgTurnaroundTime').val( avgTurnaroundTime / completedList.length );
336 | $('#avgWaitingTime').val( avgWaitingTime / completedList.length );
337 | $('#throughput').val(completedList.length / maxCompletedTime);
338 | }
339 |
340 | function roundRobin() {
341 | var timeQuantum = $('#timeQuantum');
342 | var timeQuantumVal= parseInt(timeQuantum.val(), 10);
343 | if(timeQuantum.val() ==''){
344 | alert('Please enter time quantum');
345 | timeQuantum.addClass('is-invalid');
346 | return;
347 | }
348 | var completedList = [];
349 | var time = 0;
350 | var queue = [];
351 |
352 | while (processList.length > 0 || queue.length > 0) {
353 | addToQueue();
354 | while (queue.length == 0) {
355 | time++;
356 | addToQueue();
357 | }
358 | selectProcessForRR();
359 | }
360 |
361 | function addToQueue() {
362 | for(var i = 0; i < processList.length; i++) {
363 | if(processList[i].arrivalTime === time) {
364 | var process = {
365 | processID: processList[i].processID,
366 | arrivalTime: processList[i].arrivalTime,
367 | burstTime: processList[i].burstTime
368 | }
369 | processList.splice(i, 1);
370 | queue.push(process);
371 | }
372 | }
373 | }
374 | function selectProcessForRR() {
375 | if (queue.length!=0) {
376 | queue.sort(function(a, b){
377 | if (a.burstTime > b.burstTime) {
378 | return 1;
379 | } else {
380 | return -1;
381 | }
382 | });
383 |
384 | if (queue[0].burstTime < timeQuantumVal) {
385 | process = queue.shift();
386 | process.completedTime = time + process.burstTime;
387 |
388 | for (var index = 0; index < process.burstTime; index++) {
389 | time++;
390 | addToQueue();
391 | }
392 | completedList.push(process);
393 |
394 | }
395 | else if(queue[0].burstTime == timeQuantumVal){
396 | process = queue.shift();
397 | process.completedTime = time + timeQuantumVal;
398 | completedList.push(process);
399 |
400 | for (var index = 0; index < timeQuantumVal; index++) {
401 | time++;
402 | addToQueue();
403 | }
404 | }
405 | else if(queue[0].burstTime > timeQuantumVal){
406 | process = queue[0];
407 | queue[0].burstTime = process.burstTime - timeQuantumVal;
408 |
409 | for (var index = 0; index < timeQuantumVal; index++) {
410 | time++;
411 | addToQueue();
412 | }
413 | }
414 | }
415 | }
416 |
417 | // Fetch initial table data
418 | var TableData = [];
419 | $('#tblProcessList tr').each(function(row, tr) {
420 | TableData[row] = {
421 | "processID": parseInt($(tr).find('td:eq(0)').text()),
422 | "arrivalTime": parseInt($(tr).find('td:eq(1)').text()),
423 | "burstTime": parseInt($(tr).find('td:eq(2)').text())
424 | }
425 | });
426 |
427 | // Remove table header row
428 | TableData.splice(0, 1);
429 |
430 | // Reset burst time from original input table.
431 | TableData.forEach(pInTable => {
432 | completedList.forEach(pInCompleted => {
433 | if (pInTable.processID==pInCompleted.processID) {
434 | pInCompleted.burstTime= pInTable.burstTime;
435 | pInCompleted.turnAroundTime = pInCompleted.completedTime - pInCompleted.arrivalTime;
436 | pInCompleted.waitingTime = pInCompleted.turnAroundTime - pInCompleted.burstTime;
437 | }
438 | });
439 | });
440 |
441 | // Bind table data
442 | $.each(completedList, function(key, process){
443 | $('#tblResults > tbody:last-child').append(
444 | `
445 | ${process.processID} |
446 | ${process.arrivalTime} |
447 | ${process.burstTime} |
448 | ${process.completedTime} |
449 | ${process.waitingTime} |
450 | ${process.turnAroundTime} |
451 |
`
452 | );
453 | });
454 |
455 | // Get average
456 | var totalTurnaroundTime = 0;
457 | var totalWaitingTime = 0;
458 | var maxCompletedTime = 0;
459 |
460 | $.each(completedList, function(key, process){
461 | if (process.completedTime > maxCompletedTime) {
462 | maxCompletedTime = process.completedTime;
463 | }
464 | totalTurnaroundTime = totalTurnaroundTime + process.turnAroundTime;
465 | totalWaitingTime = totalWaitingTime + process.waitingTime;
466 | });
467 |
468 | $('#avgTurnaroundTime').val( totalTurnaroundTime / completedList.length );
469 | $('#avgWaitingTime').val( totalWaitingTime / completedList.length );
470 | $('#throughput').val(completedList.length / maxCompletedTime);
471 |
472 | }
473 | }
474 | );
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | CPU Scheduling Simulator
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | Process ID |
32 | Arrival Time |
33 | Burst Time |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | Process ID |
82 | Arrival Time |
83 | Burst Time |
84 | Completed Time |
85 | Waiting Time |
86 | Turnaround Time |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
109 |
110 |
111 |
122 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | .buttonAlgo{
2 | border-radius: 15px !important;
3 | width: 70px;
4 | }
5 |
6 | #timeQuantum{
7 | width: 80px;
8 | }
--------------------------------------------------------------------------------