def test_insert_when_already_available(self): p = PageTable(2) a = read_memory_access_factory() p.insert_no_check(a) result = p.insert(a) assert result assert len(p) == 1
def test_get(self): p = PageTable(1) a = read_memory_access_factory() p.insert_no_check(a) val = p.table[0] assert p.get(a) is val assert p.get(a.page_index) is val
def __init__(self, name, sequence, table_lines): self.name = name self.sequence = deque(sequence) self.remaining = self.sequence.copy() self.id = Program.PROGRAM_ID self.page_table = PageTable(table_lines) Program.PROGRAM_ID += 1
def __init__(self, filename, alg_name, num_fames, refresh, tau): self.page_table = PageTable(num_fames) self.page_fault_counter = 0 self.memory_access_counter = 0 self.disk_write_counter = 0 self._load_replacement_algorithm(alg_name, refresh, tau) self._load_memory_accesses_from_file(filename)
def test_iterable(self): p = PageTable(3) p.insert_no_check(read_memory_access_factory()) p.insert_no_check(read_memory_access_factory('00001000')) for key, value in p: assert isinstance(key, int) assert isinstance(value, Page)
def test_insert_when_full(self): p = PageTable(1) a = read_memory_access_factory() p.insert_no_check(a) b = read_memory_access_factory('00001000') with pytest.raises(PageTableFullException): p.insert(b) assert len(p) == 1
def test_insert_when_not_full(self): p = PageTable(2) a = read_memory_access_factory() p.insert_no_check(a) b = read_memory_access_factory('00001000') with pytest.raises(PageFaultException) as e: p.insert(b) assert not isinstance(e, PageTableFullException) assert len(p) == 2
class MemoryMU(object): def __init__(self, process_list): self.page_table = PageTable() self.process_list = process_list def allocate_process_pages(self, process, physical_memory): process_pages = process.get_process_pages() process_address = self.process_list.get_process_address(process.name) for page_address, page in process_pages.items(): physicial_memory_address = physical_memory.set_page(page_address) full_address = "" + process_address + page_address self.page_table.add_route(full_address, physicial_memory_address)
class Program: PROGRAM_ID = 0 def __init__(self, name, sequence, table_lines): self.name = name self.sequence = deque(sequence) self.remaining = self.sequence.copy() self.id = Program.PROGRAM_ID self.page_table = PageTable(table_lines) Program.PROGRAM_ID += 1 def has_next_direction(self): return bool(self.remaining) def next_direction(self): return self.remaining.popleft() def print_page_table(self): self.page_table.print_table(self.id, self.name)
def __init__(self, process_list): self.page_table = PageTable() self.process_list = process_list
def skip_free_dirty_indecies(self): p = PageTable(1) a = write_memory_access_factory() p.insert_no_check(a) assert p.free_indecies(0) == 1 assert len(p) == 0
def skip_free_clean_indecies(self): p = PageTable(1) a = read_memory_access_factory() p.insert_no_check(a) assert p.free_indecies(0) == 0 assert len(p) == 0
def test_insert_with_no_checks(self): p = PageTable(1) a = read_memory_access_factory() p.insert_no_check(a) assert len(p) == 1
def test_is_full(self): p = PageTable(1) assert not p.is_full p.table[0] = True assert p.is_full
def test_length(self): p = PageTable(1) p.table[0] = True assert len(p) == 1 p.table[1] = True assert len(p) == 2
class Simulation(object): """ Virtual Memory Simulation The actual simulation to run that models virtual memory accesses in a system. Args: filename (string): the file to read the memory accesses from alg_name (string): the name of the algorithm to use for choosing the memory page to free """ def __init__(self, filename, alg_name, num_fames, refresh, tau): self.page_table = PageTable(num_fames) self.page_fault_counter = 0 self.memory_access_counter = 0 self.disk_write_counter = 0 self._load_replacement_algorithm(alg_name, refresh, tau) self._load_memory_accesses_from_file(filename) def _load_memory_accesses_from_file(self, filename): self.accesses = Queue() with open(filename) as f: for index, line in enumerate(f): self._parse_memory_access(line.strip(), index) def _load_replacement_algorithm(self, alg_name, r, t): self.alg = get_replacement_algorithm(alg_name, self.page_table, r, t) def _parse_memory_access(self, line, index): [address, access_type] = line.split(' ', 1) access = MemoryAccess(address, access_type, index) access = self.alg.preprocess_memory_access(access) self.accesses.put(access) def run(self): """ Run the simulation """ [self._handle_memory_access(access) for access in self] def _handle_memory_access(self, access): """ Handle a given memory access """ self.memory_access_counter += 1 access = self.alg.process_memory_access(access) self._insert_into_table(access) # Set the page to dirty if the access is a write page_value = self.page_table[access] page_value.referenced = True if access.write: page_value.dirty = True self.alg.postprocess_memory_access(access) def _insert_into_table(self, access): """ Load some required memory into RAM Attempts an insert into RAM for some given access. If needed, calls the right methods to free space in the page table """ try: self.page_table.insert(access) except PageFaultException as e: self._handle_page_fault(e, access) def _handle_page_fault(self, exception, access): """ Handle a page fault """ self.page_fault_counter += 1 if isinstance(exception, PageTableFullException): self._free_table_space() self.page_table.insert_no_check(access) def _free_table_space(self): num_freed_pages = self.alg.free_memory() self.disk_write_counter += num_freed_pages def __iter__(self): """ Iterate over each memory access in the simulation """ while not self.accesses.empty(): yield self.accesses.get() def __str__(self): return dedent('''\ {} Number of frames: {} Total memory accesses: {} Total page faults: {} Total writes to disk: {}''' ).format(self.alg.name, self.page_table.size, self.memory_access_counter, self.page_fault_counter, self.disk_write_counter)