diff --git a/README.md b/README.md index 0660c39..6d1f32e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Multi-Level Feedback Queue +# Multi-Level Feedback Queue ### Motivation After talking about one of the most popular scheduling algorithms used by operating systems to schedule processes, diff --git a/src/Process.js b/src/Process.js index 159a307..38aedfb 100644 --- a/src/Process.js +++ b/src/Process.js @@ -16,11 +16,16 @@ class Process { } setParentQueue(queue) { - + this.queue = queue; } isFinished() { - + if (this.blockingTimeNeeded) { + return false; + } + else { + return this.cpuTimeNeeded <= 0; + } } // If no blocking time is needed by this process, decrement the amount of @@ -29,7 +34,18 @@ class Process { // by emitting the appropriate interrupt // Make sure the `stateChanged` flag is toggled appropriately executeProcess(time) { - + const { PROCESS_BLOCKED } = SchedulerInterrupt; + if (this.blockingTimeNeeded > 0) { + this.stateChanged = !this.stateChanged; + this.queue.emitInterrupt(this, PROCESS_BLOCKED); + } + else { + for (let i = time; i > 0; i--) { + if (--this.cpuTimeNeeded == 0) { + break; + } + } + } } // If this process requires blocking time, decrement the amount of blocking @@ -38,16 +54,27 @@ class Process { // top running queue by emitting the appropriate interrupt // Make sure the `stateChanged` flag is toggled appropriately executeBlockingProcess(time) { + for (let i = time; i > 0; i--) { + if (--this.blockingTimeNeeded == 0) { + break; + } + } + + const { PROCESS_READY } = SchedulerInterrupt; + if (this.blockingTimeNeeded <= 0) { + this.stateChanged = !this.stateChanged; + this.queue.emitInterrupt(this, PROCESS_READY); + } } // Returns this process's stateChanged property isStateChanged() { - + return this.stateChanged; } get pid() { - + return this._pid; } // Private function used for testing; DO NOT MODIFY diff --git a/src/Queue.js b/src/Queue.js index 7b45fdf..ba486f0 100644 --- a/src/Queue.js +++ b/src/Queue.js @@ -18,30 +18,32 @@ class Queue { } // Enqueues the given process. Return the enqueue'd process - enqueue(process) { - - } + enqueue(process) { + process.setParentQueue(this); + this.processes.push(process); + 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() { - + return this.processes == 0; } getPriorityLevel() { - + return this.priorityLevel; } getQueueType() { - + return this.queueType; } // Manages a process's execution for the given amount of time @@ -49,26 +51,47 @@ class Queue { // 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) { + this.quantumClock = 0; + this.scheduler.handleInterrupt(this, currentProcess, SchedulerInterrupt.PROCESS_BLOCKED); + } + else if (time < this.quantum) { + this.quantumClock += time; + } + if (time > this.quantum) { + if (currentProcess.cpuTimeNeeded != 0 && currentProcess.blockingTimeNeeded === 0) { + this.scheduler.handleInterrupt(this, currentProcess, SchedulerInterrupt.LOWER_PRIORITY); + this.quantumClock = 0; + } + this.dequeue(); + } + return currentProcess; } // 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 proc = this.peek(); + proc.executeProcess(time); + this.manageTimeSlice(proc, 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 proc = this.peek(); + proc.executeBlockingProcess(time); + this.manageTimeSlice(proc, 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); } }