Skip to content
This repository has been archived by the owner on Dec 18, 2018. It is now read-only.

Sam Landsman #187

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
39 changes: 33 additions & 6 deletions src/Process.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ class Process {
}

setParentQueue(queue) {

this.queue = queue
}

isFinished() {

if (this.cpuTimeNeeded <= 0 && this.blockingTimeNeeded <= 0) {
return true
}
return false;
}

// If no blocking time is needed by this process, decrement the amount of
Expand All @@ -29,7 +32,15 @@ class Process {
// by emitting the appropriate interrupt
// Make sure the `stateChanged` flag is toggled appropriately
executeProcess(time) {

if (this.blockingTimeNeeded == 0) {
if (time > this.cpuTimeNeeded) {
time = this.cpuTimeNeeded;
}
this.cpuTimeNeeded -= time;
} else {
this.queue.emitInterrupt(this, SchedulerInterrupt.PROCESS_BLOCKED);
this.stateChanged = !this.stateChanged;
}
}

// If this process requires blocking time, decrement the amount of blocking
Expand All @@ -38,16 +49,32 @@ class Process {
// top running queue by emitting the appropriate interrupt
// Make sure the `stateChanged` flag is toggled appropriately
executeBlockingProcess(time) {

this.blockingTimeNeeded -= time;
if (this.blockingTimeNeeded < 0) {
this.blockingTimeNeeded = 0;
}
if (this.blockingTimeNeeded === 0) {
this.queue.emitInterrupt(this, SchedulerInterrupt.PROCESS_READY);
this.stateChanged = !this.stateChanged
}
// if (time > this.blockingTimeNeeded) {
// time = this.blockingTimeNeeded;
// }
// if (this.blockingTimeNeeded > 0) {
// this.blockingTimeNeeded -= time;
// } else {
// this.queue.emitInterrupt(this, SchedulerInterrupt.PROCESS_READY);
// this.stateChanged = !this.stateChanged;
// }
}

// Returns this process's stateChanged property
isStateChanged() {

return this.stateChanged;
}

get pid() {

return this._pid;
}

// Private function used for testing; DO NOT MODIFY
Expand Down
44 changes: 34 additions & 10 deletions src/Queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,56 +19,80 @@ class Queue {

// Enqueues the given process. Return the enqueue'd process
enqueue(process) {

this.processes.push(process);
process.setParentQueue(this);
return process;
}

// Dequeues the next process in the queue. Return the dequeue'd process
dequeue() {

return this.processes.shift();
}

// Return the least-recently added process without removing it from the list of processes
peek() {

return this.processes[0];
}

isEmpty() {

if (this.processes.length <= 0) {
return true;
} else {
return false;
}
}

getPriorityLevel() {

return this.priorityLevel;
}

getQueueType() {

return this.queueType;
}

// Manages a process's execution for the given amount of time
// Processes that have had their states changed should not be affected
// Once a process has received the alloted time, it needs to be dequeue'd and
// then handled accordingly, depending on whether it has finished executing or not
manageTimeSlice(currentProcess, time) {

if (currentProcess.stateChanged == true) {
this.quantumClock = 0;
return;
} else {
this.quantumClock += time;
if (this.quantumClock >= this.quantum) {
this.quantumClock = 0;
this.dequeue();
if (!currentProcess.isFinished()) {
this.scheduler.handleInterrupt(this, currentProcess, SchedulerInterrupt.LOWER_PRIORITY);
}
}
}
}

// Execute the next non-blocking process (assuming this is a CPU queue)
// This method should call `manageTimeSlice` as well as execute the next running process
doCPUWork(time) {

const process = this.peek();
process.executeProcess(time);
this.manageTimeSlice(process, time);
}

// Execute the next blocking process (assuming this is the blocking queue)
// This method should call `manageTimeSlice` as well as execute the next blocking process
doBlockingWork(time) {

const process = this.peek();
process.executeBlockingProcess(time);
this.manageTimeSlice(process, time);
}

// The queue's interrupt handler for notifying when a process needs to be moved to a different queue
// Should handle PROCESS_BLOCKED and PROCESS_READY interrupts
// The process also needs to be removed from the queue
emitInterrupt(source, interrupt) {

const sourceIndex = this.processes.indexOf(source);
this.processes.splice(sourceIndex, 1);
this.scheduler.handleInterrupt(this, source, interrupt);
}
}

Expand Down
55 changes: 51 additions & 4 deletions src/Scheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,68 @@ class Scheduler {
// On every iteration of the scheduler, if the blocking queue is not empty, blocking work
// should be done. Once the blocking work has been done, perform some CPU work in the same iteration.
run() {

while (this.allQueuesEmpty() === false) {
const time = Date.now()
const forTimeSlice = time - this.clock;
if (this.blockingQueue.isEmpty() === false) {
this.blockingQueue.doBlockingWork(forTimeSlice);
} else {
this.runningQueues.forEach(cpuQ =>{
if (!cpuQ.isEmpty()) {
cpuQ.doCPUWork(forTimeSlice);
}
})
}
this.clock = time;
}
// while (this.blockingQueue) {
// this.blockingQueue.doBlockingWork(this.clock - Date.now());
// this.clock = Date.now();
// }
// while (this.runningQueues) {
// for (let i = 0; i < PRIORITY_LEVELS; i++) {
// this.runningQueues[i].doCPUWork(this.clock - Date.now());
// this.clock = Date.now();
// }
// }
}

allQueuesEmpty() {

let empty = true;
for (let i = 0; i < PRIORITY_LEVELS; i++) {
if (this.runningQueues[i].isEmpty() === false) {
empty = false;
}
}
if (this.blockingQueue.isEmpty() === false) {
empty = false;
}
return empty;
}

addNewProcess(process) {

this.runningQueues[0].enqueue(process);
}

// The scheduler's interrupt handler that receives a queue, a process, and an interrupt string constant
// Should handle PROCESS_BLOCKED, PROCESS_READY, and LOWER_PRIORITY interrupts.
handleInterrupt(queue, process, interrupt) {

switch(interrupt) {
case "PROCESS_BLOCKED":
this.blockingQueue.enqueue(process);
break;
case "PROCESS_READY":
this.addNewProcess(process);
break;
case "LOWER_PRIORITY":
const currentQueue = this.runningQueues.indexOf(queue);
if (this.runningQueues[currentQueue + 1] && queue.getQueueType() === 'CPU_QUEUE') {
this.runningQueues[currentQueue + 1].enqueue(process);
} else {
queue.enqueue(process);
}
break;
}
}

// Private function used for testing; DO NOT MODIFY
Expand Down