├── 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 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
Process IDArrival TimeBurst Time
40 |
41 |
42 | 43 |
44 |
45 | 46 |
47 |
48 | 49 |
50 |
51 | 52 |
53 |
54 |
55 |
56 |
57 |
58 | 59 | 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 |
Process IDArrival TimeBurst TimeCompleted TimeWaiting TimeTurnaround Time
92 |
93 |
94 |
95 |
96 | 97 | 98 |
99 |
100 | 101 | 102 |
103 |
104 | 105 | 106 |
107 |
108 |
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 | } --------------------------------------------------------------------------------