completion time of finished process or last interrupted time mlfqmulti level feedback queue https en wikipedia orgwikimultilevelfeedbackqueue mlfq has a lot of queues that have different priority in this mlfq the first queue0 to last second queuen2 of mlfq have round robin algorithm the last queuen1 has first come first served algorithm total number of mlfq s queues time slice of queues that round robin algorithm applied unfinished process is in this readyqueue current time finished process is in this sequence queue this method returns the sequence of finished processes p1 processp1 0 53 p2 processp2 0 17 p3 processp3 0 68 p4 processp4 0 24 mlfq mlfq3 17 25 dequep1 p2 p3 p4 0 mlfq multilevelfeedbackqueue mlfq calculatesequenceoffinishqueue p2 p4 p1 p3 this method calculates waiting time of processes p1 processp1 0 53 p2 processp2 0 17 p3 processp3 0 68 p4 processp4 0 24 mlfq mlfq3 17 25 dequep1 p2 p3 p4 0 mlfq multilevelfeedbackqueue mlfq calculatewaitingtimep1 p2 p3 p4 83 17 94 101 this method calculates turnaround time of processes p1 processp1 0 53 p2 processp2 0 17 p3 processp3 0 68 p4 processp4 0 24 mlfq mlfq3 17 25 dequep1 p2 p3 p4 0 mlfq multilevelfeedbackqueue mlfq calculateturnaroundtimep1 p2 p3 p4 136 34 162 125 this method calculates completion time of processes p1 processp1 0 53 p2 processp2 0 17 p3 processp3 0 68 p4 processp4 0 24 mlfq mlfq3 17 25 dequep1 p2 p3 p4 0 mlfq multilevelfeedbackqueue mlfq calculateturnaroundtimep1 p2 p3 p4 136 34 162 125 this method calculate remaining burst time of processes p1 processp1 0 53 p2 processp2 0 17 p3 processp3 0 68 p4 processp4 0 24 mlfq mlfq3 17 25 dequep1 p2 p3 p4 0 finishqueue readyqueue mlfq roundrobindequep1 p2 p3 p4 17 mlfq calculateremainingbursttimeofprocessesmlfq finishqueue 0 mlfq calculateremainingbursttimeofprocessesreadyqueue 36 51 7 finishqueue readyqueue mlfq roundrobinreadyqueue 25 mlfq calculateremainingbursttimeofprocessesmlfq finishqueue 0 0 mlfq calculateremainingbursttimeofprocessesreadyqueue 11 26 this method updates waiting times of unfinished processes p1 processp1 0 53 p2 processp2 0 17 p3 processp3 0 68 p4 processp4 0 24 mlfq mlfq3 17 25 dequep1 p2 p3 p4 0 mlfq currenttime 10 p1 stoptime 5 mlfq updatewaitingtimep1 5 fcfsfirst come first served fcfs will be applied to mlfq s last queue a first came process will be finished at first p1 processp1 0 53 p2 processp2 0 17 p3 processp3 0 68 p4 processp4 0 24 mlfq mlfq3 17 25 dequep1 p2 p3 p4 0 mlfq firstcomefirstservedmlfq readyqueue mlfq calculatesequenceoffinishqueue p1 p2 p3 p4 if process s arrival time is later than current time update current time update waiting time of current process update current time finish the process and set the process s bursttime 0 set the process s turnaround time because it is finished set the completion time add the process to queue that has finished queue fcfs will finish all remaining processes rrround robin rr will be applied to mlfq s all queues except last queue all processes can t use cpu for time more than timeslice if the process consume cpu up to timeslice it will go back to ready queue p1 processp1 0 53 p2 processp2 0 17 p3 processp3 0 68 p4 processp4 0 24 mlfq mlfq3 17 25 dequep1 p2 p3 p4 0 finishqueue readyqueue mlfq roundrobinmlfq readyqueue 17 mlfq calculatesequenceoffinishqueue p2 just for 1 cycle and unfinished processes will go back to queue if process s arrival time is later than current time update current time update waiting time of unfinished processes if the burst time of process is bigger than timeslice use cpu for only timeslice update remaining burst time update end point time locate the process behind the queue because it is not finished use cpu for remaining burst time set burst time 0 because the process is finished set the finish time update the process turnaround time because it is finished add the process to queue that has finished queue return finished processes queue and remaining processes queue mlfqmulti level feedback queue p1 processp1 0 53 p2 processp2 0 17 p3 processp3 0 68 p4 processp4 0 24 mlfq mlfq3 17 25 dequep1 p2 p3 p4 0 finishqueue mlfq multilevelfeedbackqueue mlfq calculatesequenceoffinishqueue p2 p4 p1 p3 all queues except last one have roundrobin algorithm the last queue has firstcomefirstserved algorithm print total waiting times of processesp1 p2 p3 p4 print completion times of processesp1 p2 p3 p4 print total turnaround times of processesp1 p2 p3 p4 print sequence of finished processes process name arrival time of the process completion time of finished process or last interrupted time remaining burst time total time of the process wait in ready queue time from arrival time to completion time mlfq multi level feedback queue https en wikipedia org wiki multilevel_feedback_queue mlfq has a lot of queues that have different priority in this mlfq the first queue 0 to last second queue n 2 of mlfq have round robin algorithm the last queue n 1 has first come first served algorithm total number of mlfq s queues time slice of queues that round robin algorithm applied unfinished process is in this ready_queue current time finished process is in this sequence queue this method returns the sequence of finished processes p1 process p1 0 53 p2 process p2 0 17 p3 process p3 0 68 p4 process p4 0 24 mlfq mlfq 3 17 25 deque p1 p2 p3 p4 0 _ mlfq multi_level_feedback_queue mlfq calculate_sequence_of_finish_queue p2 p4 p1 p3 this method calculates waiting time of processes p1 process p1 0 53 p2 process p2 0 17 p3 process p3 0 68 p4 process p4 0 24 mlfq mlfq 3 17 25 deque p1 p2 p3 p4 0 _ mlfq multi_level_feedback_queue mlfq calculate_waiting_time p1 p2 p3 p4 83 17 94 101 this method calculates turnaround time of processes p1 process p1 0 53 p2 process p2 0 17 p3 process p3 0 68 p4 process p4 0 24 mlfq mlfq 3 17 25 deque p1 p2 p3 p4 0 _ mlfq multi_level_feedback_queue mlfq calculate_turnaround_time p1 p2 p3 p4 136 34 162 125 this method calculates completion time of processes p1 process p1 0 53 p2 process p2 0 17 p3 process p3 0 68 p4 process p4 0 24 mlfq mlfq 3 17 25 deque p1 p2 p3 p4 0 _ mlfq multi_level_feedback_queue mlfq calculate_turnaround_time p1 p2 p3 p4 136 34 162 125 this method calculate remaining burst time of processes p1 process p1 0 53 p2 process p2 0 17 p3 process p3 0 68 p4 process p4 0 24 mlfq mlfq 3 17 25 deque p1 p2 p3 p4 0 finish_queue ready_queue mlfq round_robin deque p1 p2 p3 p4 17 mlfq calculate_remaining_burst_time_of_processes mlfq finish_queue 0 mlfq calculate_remaining_burst_time_of_processes ready_queue 36 51 7 finish_queue ready_queue mlfq round_robin ready_queue 25 mlfq calculate_remaining_burst_time_of_processes mlfq finish_queue 0 0 mlfq calculate_remaining_burst_time_of_processes ready_queue 11 26 this method updates waiting times of unfinished processes p1 process p1 0 53 p2 process p2 0 17 p3 process p3 0 68 p4 process p4 0 24 mlfq mlfq 3 17 25 deque p1 p2 p3 p4 0 mlfq current_time 10 p1 stop_time 5 mlfq update_waiting_time p1 5 fcfs first come first served fcfs will be applied to mlfq s last queue a first came process will be finished at first p1 process p1 0 53 p2 process p2 0 17 p3 process p3 0 68 p4 process p4 0 24 mlfq mlfq 3 17 25 deque p1 p2 p3 p4 0 _ mlfq first_come_first_served mlfq ready_queue mlfq calculate_sequence_of_finish_queue p1 p2 p3 p4 sequence deque of finished process current process if process s arrival time is later than current time update current time update waiting time of current process update current time finish the process and set the process s burst time 0 set the process s turnaround time because it is finished set the completion time add the process to queue that has finished queue add finished process to finish queue fcfs will finish all remaining processes rr round robin rr will be applied to mlfq s all queues except last queue all processes can t use cpu for time more than time_slice if the process consume cpu up to time_slice it will go back to ready queue p1 process p1 0 53 p2 process p2 0 17 p3 process p3 0 68 p4 process p4 0 24 mlfq mlfq 3 17 25 deque p1 p2 p3 p4 0 finish_queue ready_queue mlfq round_robin mlfq ready_queue 17 mlfq calculate_sequence_of_finish_queue p2 sequence deque of terminated process just for 1 cycle and unfinished processes will go back to queue current process if process s arrival time is later than current time update current time update waiting time of unfinished processes if the burst time of process is bigger than time slice use cpu for only time slice update remaining burst time update end point time locate the process behind the queue because it is not finished use cpu for remaining burst time set burst time 0 because the process is finished set the finish time update the process turnaround time because it is finished add the process to queue that has finished queue add finished process to finish queue return finished processes queue and remaining processes queue mlfq multi level feedback queue p1 process p1 0 53 p2 process p2 0 17 p3 process p3 0 68 p4 process p4 0 24 mlfq mlfq 3 17 25 deque p1 p2 p3 p4 0 finish_queue mlfq multi_level_feedback_queue mlfq calculate_sequence_of_finish_queue p2 p4 p1 p3 all queues except last one have round_robin algorithm the last queue has first_come_first_served algorithm print total waiting times of processes p1 p2 p3 p4 print completion times of processes p1 p2 p3 p4 print total turnaround times of processes p1 p2 p3 p4 print sequence of finished processes
from collections import deque


class Process:
    def __init__(self, process_name: str, arrival_time: int, burst_time: int) -> None:
        self.process_name = process_name  
        self.arrival_time = arrival_time  
        
        self.stop_time = arrival_time
        self.burst_time = burst_time  
        self.waiting_time = 0  
        self.turnaround_time = 0  


class MLFQ:
    

    def __init__(
        self,
        number_of_queues: int,
        time_slices: list[int],
        queue: deque[Process],
        current_time: int,
    ) -> None:
        
        self.number_of_queues = number_of_queues
        
        self.time_slices = time_slices
        
        self.ready_queue = queue
        
        self.current_time = current_time
        
        self.finish_queue: deque[Process] = deque()

    def calculate_sequence_of_finish_queue(self) -> list[str]:
        
        sequence = []
        for i in range(len(self.finish_queue)):
            sequence.append(self.finish_queue[i].process_name)
        return sequence

    def calculate_waiting_time(self, queue: list[Process]) -> list[int]:
        
        waiting_times = []
        for i in range(len(queue)):
            waiting_times.append(queue[i].waiting_time)
        return waiting_times

    def calculate_turnaround_time(self, queue: list[Process]) -> list[int]:
        
        turnaround_times = []
        for i in range(len(queue)):
            turnaround_times.append(queue[i].turnaround_time)
        return turnaround_times

    def calculate_completion_time(self, queue: list[Process]) -> list[int]:
        
        completion_times = []
        for i in range(len(queue)):
            completion_times.append(queue[i].stop_time)
        return completion_times

    def calculate_remaining_burst_time_of_processes(
        self, queue: deque[Process]
    ) -> list[int]:
        
        return [q.burst_time for q in queue]

    def update_waiting_time(self, process: Process) -> int:
        
        process.waiting_time += self.current_time - process.stop_time
        return process.waiting_time

    def first_come_first_served(self, ready_queue: deque[Process]) -> deque[Process]:
        
        finished: deque[Process] = deque()  
        while len(ready_queue) != 0:
            cp = ready_queue.popleft()  

            
            if self.current_time < cp.arrival_time:
                self.current_time += cp.arrival_time

            
            self.update_waiting_time(cp)
            
            self.current_time += cp.burst_time
            
            cp.burst_time = 0
            
            cp.turnaround_time = self.current_time - cp.arrival_time
            
            cp.stop_time = self.current_time
            
            finished.append(cp)

        self.finish_queue.extend(finished)  
        
        return finished

    def round_robin(
        self, ready_queue: deque[Process], time_slice: int
    ) -> tuple[deque[Process], deque[Process]]:
        
        finished: deque[Process] = deque()  
        
        for _ in range(len(ready_queue)):
            cp = ready_queue.popleft()  

            
            if self.current_time < cp.arrival_time:
                self.current_time += cp.arrival_time

            
            self.update_waiting_time(cp)
            
            if cp.burst_time > time_slice:
                
                self.current_time += time_slice
                
                cp.burst_time -= time_slice
                
                cp.stop_time = self.current_time
                
                ready_queue.append(cp)
            else:
                
                self.current_time += cp.burst_time
                
                cp.burst_time = 0
                
                cp.stop_time = self.current_time
                
                cp.turnaround_time = self.current_time - cp.arrival_time
                
                finished.append(cp)

        self.finish_queue.extend(finished)  
        
        return finished, ready_queue

    def multi_level_feedback_queue(self) -> deque[Process]:
        

        
        for i in range(self.number_of_queues - 1):
            finished, self.ready_queue = self.round_robin(
                self.ready_queue, self.time_slices[i]
            )
        
        self.first_come_first_served(self.ready_queue)

        return self.finish_queue


if __name__ == "__main__":
    import doctest

    P1 = Process("P1", 0, 53)
    P2 = Process("P2", 0, 17)
    P3 = Process("P3", 0, 68)
    P4 = Process("P4", 0, 24)
    number_of_queues = 3
    time_slices = [17, 25]
    queue = deque([P1, P2, P3, P4])

    if len(time_slices) != number_of_queues - 1:
        raise SystemExit(0)

    doctest.testmod(extraglobs={"queue": deque([P1, P2, P3, P4])})

    P1 = Process("P1", 0, 53)
    P2 = Process("P2", 0, 17)
    P3 = Process("P3", 0, 68)
    P4 = Process("P4", 0, 24)
    number_of_queues = 3
    time_slices = [17, 25]
    queue = deque([P1, P2, P3, P4])
    mlfq = MLFQ(number_of_queues, time_slices, queue, 0)
    finish_queue = mlfq.multi_level_feedback_queue()

    
    print(
        f"waiting time:\
        \t\t\t{MLFQ.calculate_waiting_time(mlfq, [P1, P2, P3, P4])}"
    )
    
    print(
        f"completion time:\
        \t\t{MLFQ.calculate_completion_time(mlfq, [P1, P2, P3, P4])}"
    )
    
    print(
        f"turnaround time:\
        \t\t{MLFQ.calculate_turnaround_time(mlfq, [P1, P2, P3, P4])}"
    )
    
    print(
        f"sequence of finished processes:\
        {mlfq.calculate_sequence_of_finish_queue()}"
    )