def start_daemon(self): while self.__is_running: if self.kernel.has_io_jobs(): sync_print('DEBUG: [DMAChannel] Activated!' ) if DMAChannelDEBUG is True else None pcb = self.kernel.get_job_from_io_queue() logical_address = LogicalAddress() cached = self.kernel.get_pages_from_io_queue(pcb) for page_num in cached: pcb.io_operations += 1 logical_address.set_page_number(page_num) # -- get page table -- # page_table = pcb.get_page_table() # -- find page in ram -- # ram_address = page_table.get_page(page_num) # -- copy ram --> cache -- # pcb_cache = pcb.cpu_state.get_cache() for page_offset in range(PAGE_SIZE): logical_address.set_page_offset(page_offset) data = self.ram.read_ram(ram_address, page_address=page_offset) pcb_cache.write_cache(logical_address, data) # -- set valid/dirty bits -- # pcb_cache.set_valid_page(page_num, True) pcb_cache.set_dirty_page(page_num, False) # -- Completed, remove from queue -- # self.kernel.remove_from_io_queue(pcb) sync_print( f'DEBUG: [DMAChannel] Ended with PID {pcb.job_id} state {pcb.state}' ) if DMAChannelDEBUG is True else None
def print_ram(self, n=None): """ DEBUGGING """ c = 0 for page in self.ram: for i in range(4): if n is not None and n < c: return c += 1 sync_print(page.read_page(i))
def __init__(self, program_file: str): self.disk = Disk() self.ram = RAM() self.kernel = Kernel() self.page_manager = PageManager( disk=self.disk, kernel=self.kernel, ram=self.ram, ) self.loader = Loader(disk=self.disk, kernel=self.kernel, program_file=program_file) sync_print('DEBUG: [OSDriver] __init__ completed.' ) if OS_DRIVER_DEBUG is True else None
def start_daemon(self): while self.__is_running is True: # -- Continue Here -- # if self.kernel.has_page_fault_jobs() is True and self.is_page_available() is True: sync_print('DEBUG: [Page Manager] Activated!') if PageManagerDEBUG is True else None pcb: PCB = self.kernel.get_job_from_page_fault_queue() page_faults: list = self.kernel.get_pages_from_page_fault_queue(pcb) for page_num in page_faults: pcb.page_fault_operations += 1 disk_index = pcb.get_disk_address_begin() + page_num page_index = self.free_page_pool.pop(0) self.ram.write_ram(address=page_index, page_data=self.disk.read_disk(disk_index)) pcb.get_page_table().write_page_table(page_num=page_num, ram_address=page_index) self.kernel.remove_from_page_fault_queue(pcb) sync_print('DEBUG: [Page Manager] Ended!') if PageManagerDEBUG is True else None
def check_for_interrupt(self, logical_address: LogicalAddress, cache: Cache, pcb: PCB) -> bool: is_interrupt = False page_num = logical_address.get_page_number() if cache.is_page_valid(logical_address=logical_address) is False: if pcb.get_page_table().is_valid(page_num) is False: sync_print( 'DEBUG: [MMU] Page Fault.') if MMU_DEBUG is True else None self.kernel.add_to_page_fault_queue(pcb, page_num) else: sync_print( 'DEBUG: [MMU] IO Queue.') if MMU_DEBUG is True else None self.kernel.add_to_io_queue(pcb, page_num) pcb.set_state(WAITING_STATE) is_interrupt = True return is_interrupt
def run_process(self): self.is_spinning = True while self.is_spinning is True: pc = self.cpu_state.get_pc() instruction_str = self.fetch(address=self.cpu_state.get_pc()) self.cpu_state.increment_pc() if self.cpu_is_interrupted is False: self.decode(instruction_str) instruction = self.cpu_state.get_instruction() sync_print( f'DEBUG: [CPU_ID {self.cpu_id} PID {self.current_pcb.job_id} pc {pc}]' f' Fetch {instruction_str} -> {instruction}' ) if CPU_DEBUG is True else None if instruction.format == '0x0': self.execute_arithmetic( opcode_hex=instruction.opcode, s1_hex=instruction.reg1, s2_hex=instruction.reg2, dr_hex=instruction.address, ) elif instruction.format == '0x1': self.execute_conditional_branch( opcode_hex=instruction.opcode, br_hex=instruction.breg, dr_hex=instruction.dstreg, address_hex=instruction.address, ) elif instruction.format == '0x2': self.execute_unconditional_jump( opcode_hex=instruction.opcode, address_hex=instruction.address, ) elif instruction.format == '0x3': self.execute_io(opcode_hex=instruction.opcode, r1_hex=instruction.reg1, r2_hex=instruction.reg2, address_hex=instruction.address) else: raise UnexpectedCPUError( f'run_process(...) unable to match instruction->format {instruction.format}.' ) if self.cpu_is_interrupted is True: self.cpu_state.decrement_pc() self.cpu_is_interrupted = False
def run(self): start_time = time.time() if SCHEDULING_TYPE == 'FIFO': self.kernel.sort_by_fifo() elif SCHEDULING_TYPE == 'SJF': self.kernel.sort_by_shortest_job_first() elif SCHEDULING_TYPE == 'Priority': self.kernel.sort_by_priority() else: raise UnexpectedOSDriverError( f'Unsupported SCHEDULING_TYPE {SCHEDULING_TYPE}.') self.ram.init_page_manager(self.page_manager) CORE_DUMPS.set_ram(ram=self.ram) ls = LongScheduler(ram=self.ram, disk=self.disk, kernel=self.kernel) ls.run() sync_print( f'DEBUG: [OSDriver] LongScheduler loaded {self.kernel.get_queue_size()} jobs.' ) if OS_DRIVER_DEBUG is True else None ss = ShortScheduler(ram=self.ram, kernel=self.kernel, page_manager=self.page_manager) ss.run() sync_print('DEBUG: [OSDriver] ShortScheduler completed.' ) if OS_DRIVER_DEBUG is True else None # -- Waiting to finish -- # for cpu in ss.cpu_bank: while cpu.is_process_running() is True: pass sync_print( f'DEBUG: [OSDriver] CPU {cpu.cpu_id} completed {cpu.jobs_completed} jobs.' ) if OS_DRIVER_DEBUG is True else None sync_print( f'DEBUG: [OSDriver] Final in {round(time.time()-start_time, ndigits=2)}s.' ) if OS_DRIVER_DEBUG is True else None # -- Create the Disk Core Dump -- # CORE_DUMPS.create_disk_dump(self.disk) # -- Save the Core Dumps to file -- # CORE_DUMPS.save_to_file() # -- Print Stats Report -- # statistics.print_report()
def print_cache(self): """ Troubleshooting """ sync_print('------------------------------') for page in self.cache: for i in range(4): sync_print(page.page[i]) sync_print('------------------------------')
def set_state(self, state: str): statistics.process_state_change(pcb=self, old_state=self.state, new_state=state) self.state = state sync_print(f'DEBUG: STATE {self.state} PID {self.job_id}') if PCB_DEBUG is True else None
def print_page_table(self): sync_print('-----------------------') for i in range(self.page_count): sync_print(f'table page_num {i} -> ram_addr {self.table[i]}') sync_print('-----------------------')