0% found this document useful (0 votes)
16 views

Os Lab File

The document discusses different page replacement algorithms like FIFO, LRU and LFU. It provides code implementations of these algorithms and examples to simulate their behavior on sample page reference strings. The algorithms handle page faults by replacing pages based on their recency or frequency of use.

Uploaded by

Ravindra Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

Os Lab File

The document discusses different page replacement algorithms like FIFO, LRU and LFU. It provides code implementations of these algorithms and examples to simulate their behavior on sample page reference strings. The algorithms handle page faults by replacing pages based on their recency or frequency of use.

Uploaded by

Ravindra Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 42

B.

TECH 3 rd year
SUBJECT : OPERATING SYSTEM
SUBJECT CODE :- BT CS 605A

Submitted To : Submitted By :
Dr. Benay Kumar Ray Parmod Kumar
(211572)
Program to Simulate Bankers Algorithm for Dead Lock
Avoidance and Prevention

def is_safe_state(available, allocation, max_need):


num_processes = len(allocation)
num_resources = len(available)
work = available[:]
finish = [False] * num_processes
safe_sequence = []

while True:
found = False
for i in range(num_processes):
if not finish[i] and all(need <= work for need, work in
zip(max_need[i], work)):
found = True
finish[i] = True
safe_sequence.append(i)
for j in range(num_resources):
work[j] += allocation[i][j]
break

if not found:
break

return all(finish), safe_sequence

if __name__ == "__main__":
allocation = [
[0, 1, 0],
[2, 0, 0],
[3, 0, 2],
[2, 1, 1],
[0, 0, 2]
]
max_need = [
[7, 5, 3],
[3, 2, 2],
[9, 0, 2],
[2, 2, 2],
[4, 3, 3]
]
available = [3, 3, 2]

safe, sequence = is_safe_state(available, allocation, max_need)


if safe:
print("The system is in a safe state.")
print("Safe sequence (processes in order):", [f"P{p}" for p in
sequence])
else:
print("The system is in an unsafe state. Deadlock may occur.")

# Finding the safe sequence


n = len(allocation)
m = len(available)
f = [0] * n
ans = [0] * n
ind = 0
for k in range(n):
f[k] = 0
need = [[0 for i in range(m)] for i in range(n)]
for i in range(n):
for j in range(m):
need[i][j] = max_need[i][j] - allocation[i][j]
for k in range(n):
for i in range(n):
if f[i] == 0:
flag = 0
for j in range(m):
if need[i][j] > available[j]:
flag = 1
break

if flag == 0:
ans[ind] = i
ind += 1
for y in range(m):
available[y] += allocation[i][y]
f[i] = 1
print("\nExplaining the Safe Sequence:")
print("The safe sequence of processes ensures that the system can
avoid deadlock and complete execution.")
print("Safe sequence (processes in order):", [f"P{p}" for p in
ans])

Output:
Program to simulate MVT and MFT memory
management techniques
MVT:
class MVTMemory:
def __init__(self, total_memory):
self.total_memory = total_memory
self.memory_map = [(0, total_memory)] # Initial memory map
with one free block spanning the entire memory

def allocate_memory(self, process_id, size):


"""Allocate memory for a process."""
for i, (start, end) in enumerate(self.memory_map):
if end - start >= size:
self.memory_map[i] = (start + size, end) # Update
free block
return start, start + size, True
return -1, -1, False # Allocation failed

def deallocate_memory(self, start):


"""Deallocate memory for a process."""
for i, (block_start, block_end) in enumerate(self.memory_map):
if block_start == start:
if i > 0 and block_start == self.memory_map[i - 1][1]:
# Merge with previous block if adjacent
self.memory_map[i - 1] = (self.memory_map[i - 1]
[0], block_end)
del self.memory_map[i]
else:
self.memory_map[i] = (block_start, block_start +
(block_end - block_start))
return True
return False # Deallocation failed
def print_memory_map(self):
"""Print the current memory map."""
print("Memory Map:")
print("Start\tEnd\tProcess ID")
for start, end in self.memory_map:
print(start, "\t", end)

# Example usage for MVT


if __name__ == "__main__":
total_memory = 1000
mvt_memory = MVTMemory(total_memory)

processes = [(1, 200), (2, 300), (3, 400)]


for process_id, size in processes:
start, end, success = mvt_memory.allocate_memory(process_id,
size)
if success:
print("Process", process_id, "allocated from", start,
"to", end)
else:
print("Failed to allocate memory for Process", process_id)

mvt_memory.print_memory_map()

mvt_memory.deallocate_memory(200)
mvt_memory.deallocate_memory(400)

mvt_memory.print_memory_map()
OUTPUT:

MFT:
class MFTMemory:
def __init__(self, total_memory, block_size):
self.total_memory = total_memory
self.block_size = block_size
self.num_blocks = total_memory // block_size
self.memory_map = [(i * block_size, (i + 1) * block_size,
None) for i in range(self.num_blocks)]

def allocate_memory(self, process_id, size):


"""Allocate memory for a process."""
required_blocks = size // self.block_size + (1 if size %
self.block_size != 0 else 0)
for i, (start, end, pid) in enumerate(self.memory_map):
if pid is None and i + required_blocks <= self.num_blocks:
allocated_blocks = []
for j in range(i, i + required_blocks):
allocated_blocks.append(j)
self.memory_map[j] = (self.memory_map[j][0],
self.memory_map[j][1], process_id)
return allocated_blocks, True
return [], False # Allocation failed
def deallocate_memory(self, allocated_blocks):
"""Deallocate memory for a process."""
for i in allocated_blocks:
self.memory_map[i] = (self.memory_map[i][0],
self.memory_map[i][1], None)

def print_memory_map(self):
"""Print the current memory map."""
print("Memory Map:")
print("Start\tEnd\tProcess ID")
for start, end, pid in self.memory_map:
print(start, "\t", end, "\t", pid if pid is not None else
"Free")

# Example usage for MFT


if __name__ == "__main__":
total_memory = 1000
block_size = 100
mft_memory = MFTMemory(total_memory, block_size)

processes = [(1, 200), (2, 300), (3, 400)]


for process_id, size in processes:
allocated_blocks, success =
mft_memory.allocate_memory(process_id, size)
if success:
print("Process", process_id, "allocated to blocks:",
allocated_blocks)
else:
print("Failed to allocate memory for Process", process_id)

mft_memory.print_memory_map()
mft_memory.deallocate_memory([0, 1, 2, 3, 4])
mft_memory.deallocate_memory([5, 6, 7])

mft_memory.print_memory_map()

Output:
Program to simulate page replacement algorithms
FIFO:
class FIFOPageReplacement:
def __init__(self, capacity):
self.capacity = capacity
self.pages = []

def page_fault(self, page):


"""Handle page faults using FIFO page replacement
algorithm."""
if page not in self.pages:
if len(self.pages) == self.capacity:
self.pages.pop(0) # Remove the oldest page
self.pages.append(page) # Add the new page
return True # Page fault occurred
return False # Page is already in memory

def display_pages(self):
"""Display pages currently in memory."""
print("Pages in memory:", self.pages)

# Example usage for FIFO


if __name__ == "__main__":
fifo = FIFOPageReplacement(3) # Capacity of 3 pages

pages = [1, 2, 3, 4, 1, 2]
for page in pages:
if fifo.page_fault(page):
print("Page", page, "caused a page fault")
else:
print("Page", page, "is already in memory")
fifo.display_pages()

OUTPUT:

LRU:
class LRUPageReplacement:
def __init__(self, capacity):
self.capacity = capacity
self.pages = []

def page_fault(self, page):


"""Handle page faults using LRU page replacement algorithm."""
if page not in self.pages:
if len(self.pages) == self.capacity:
self.pages.pop(0) # Remove the least recently used
page
self.pages.append(page) # Add the new page
return True # Page fault occurred
else:
self.pages.remove(page) # Move the accessed page to the
end (most recently used)
self.pages.append(page)
return False # Page is already in memory

def display_pages(self):
"""Display pages currently in memory."""
print("Pages in memory:", self.pages)

# Example usage for LRU


if __name__ == "__main__":
lru = LRUPageReplacement(3) # Capacity of 3 pages

pages = [1, 2, 3, 4, 1, 2]
for page in pages:
if lru.page_fault(page):
print("Page", page, "caused a page fault")
else:
print("Page", page, "is already in memory")
lru.display_pages()

OUTPUT:
LFU:
from collections import defaultdict

class LFUPageReplacement:
def __init__(self, capacity):
self.capacity = capacity
self.pages = []
self.frequency = defaultdict(int)

def page_fault(self, page):


"""Handle page faults using LFU page replacement algorithm."""
if page not in self.pages:
if len(self.pages) == self.capacity:
min_frequency_page = min(self.pages, key=lambda x:
self.frequency[x])
self.pages.remove(min_frequency_page)
del self.frequency[min_frequency_page]
self.pages.append(page)
self.frequency[page] += 1
return page not in self.pages

def display_pages(self):
"""Display pages currently in memory."""
print("Pages in memory:", self.pages)

# Example usage for LFU


if __name__ == "__main__":
lfu = LFUPageReplacement(3) # Capacity of 3 pages

pages = [1, 2, 3, 4, 1, 2]
for page in pages:
if lfu.page_fault(page):
print("Page", page, "caused a page fault")
else:
print("Page", page, "is already in memory")
lfu.display_pages()

OUTPUT:
ROUND ROBIN:
def round_robin(processes, burst_time, quantum):
n = len(processes)
remaining_burst_time = burst_time[:]
time = 0
waiting_time = [0] * n
turnaround_time = [0] * n
timeline = [] # Timeline to store the sequence of processes
executed

while True:
done = True
for i in range(n):
if remaining_burst_time[i] > 0:
done = False
if remaining_burst_time[i] > quantum:
timeline.append(processes[i]) # Add process to
timeline
time += quantum
remaining_burst_time[i] -= quantum
else:
timeline.append(processes[i]) # Add process to
timeline
time += remaining_burst_time[i]
waiting_time[i] = time - burst_time[i]
remaining_burst_time[i] = 0

if done:
break

for i in range(n):
turnaround_time[i] = burst_time[i] + waiting_time[i]

return waiting_time, turnaround_time, timeline

# Example usage:
processes = [1, 2, 3, 4]
burst_time = [8, 6, 1, 9]
quantum = 2

waiting_time, turnaround_time, timeline = round_robin(processes,


burst_time, quantum)
print("Round Robin Waiting Time:", waiting_time)
print("Round Robin Turnaround Time:", turnaround_time)

# Print Gantt Chart


print("\nGantt Chart:")
print("-" * 30)
print("|", end="")
for process in timeline:
print(f" P{process} |", end="")
print("\n" + "-" * 30)
print("|", end="")
for i in range(len(timeline)):
print(f" {i * quantum:2d} |", end="")
print("\n" + "-" * 30)

OUTPUT:
Shortest Job First(SJF):
def sjf(processes, burst_time):
n = len(processes)
waiting_time = [0] * n
turnaround_time = [0] * n
timeline = [] # Timeline to store the sequence of processes
executed

# Sort processes based on burst time


sorted_processes = sorted(range(n), key=lambda i: burst_time[i])

# Calculate waiting time for each process


for i in range(1, n):
waiting_time[sorted_processes[i]] = sum(burst_time[:i])

# Calculate turnaround time for each process


for i in range(n):
turnaround_time[sorted_processes[i]] =
burst_time[sorted_processes[i]] + waiting_time[sorted_processes[i]]

# Generate simplified timeline


timeline.append(processes[sorted_processes[0]])
for i in range(1, n):
if processes[sorted_processes[i]] !=
processes[sorted_processes[i-1]]:
timeline.append(processes[sorted_processes[i]])

return waiting_time, turnaround_time, timeline

def print_table(processes, burst_time, waiting_time, turnaround_time):


print("Process\tBurst Time\tWaiting Time\tTurnaround Time")
for i in range(len(processes)):
print(f"P{processes[i]}\t{burst_time[i]}\t\t{waiting_time[i]}\
t\t{turnaround_time[i]}")

# Example usage:
processes = [1, 2, 3, 4]
burst_time = [8, 6, 1, 9]

waiting_time, turnaround_time, timeline = sjf(processes, burst_time)


print("SJF Waiting Time:", waiting_time)
print("SJF Turnaround Time:", turnaround_time)

print("\nProcess Table:")
# Print table of processes, burst time, waiting time, and turnaround
time

print_table(processes, burst_time, waiting_time, turnaround_time)

# Print Simplified Gantt Chart


print("\nSimplified Gantt Chart:")
print("-" * 30)
print("|", end="")
prev_process = timeline[0]
for process in timeline:
if process != prev_process:
print(f" P{prev_process} |", end="")
prev_process = process
print(f" P{prev_process} |", end="")
print("\n" + "-" * 30)
print("|", end="")
for i in range(len(timeline)):
print(f" {i:2d} |", end="")
print("\n" + "-" * 30)

OUTPUT:
First Come First Serve(FCFS):
def fcfs(processes, burst_time):
n = len(processes)
waiting_time = [0] * n
turnaround_time = [0] * n
timeline = [] # Timeline to store the sequence of processes
executed

# Calculate waiting time for each process


for i in range(1, n):
waiting_time[i] = sum(burst_time[:i])

# Calculate turnaround time for each process


for i in range(n):
turnaround_time[i] = burst_time[i] + waiting_time[i]

# Generate simplified timeline


timeline.append(processes[0])
for i in range(1, n):
if processes[i] != processes[i-1]:
timeline.append(processes[i])

return waiting_time, turnaround_time, timeline

# Example usage:
processes = [1, 2, 3, 4]
burst_time = [8, 6, 1, 9]

waiting_time, turnaround_time, timeline = fcfs(processes, burst_time)


print("FCFS Waiting Time:", waiting_time)
print("FCFS Turnaround Time:", turnaround_time)
# Print Simplified Gantt Chart
print("\nSimplified Gantt Chart:")
print("-" * 30)
print("|", end="")
prev_process = timeline[0]
for process in timeline:
if process != prev_process:
print(f" P{prev_process} |", end="")
prev_process = process
print(f" P{prev_process} |", end="")
print("\n" + "-" * 30)
print("|", end="")
for i in range(len(timeline)):
print(f" {i:2d} |", end="")
print("\n" + "-" * 30)

OUTPUT:
PRIORITY:
def priority_non_preemptive(processes, burst_time, priority):
n = len(processes)
waiting_time = [0] * n
turnaround_time = [0] * n
timeline = [] # Timeline to store the sequence of processes
executed

# Sort processes based on priority


sorted_processes = sorted(range(n), key=lambda x: priority[x])

# Calculate waiting time for each process


waiting_time[sorted_processes[0]] = 0
for i in range(1, n):
waiting_time[sorted_processes[i]] =
burst_time[sorted_processes[i - 1]] + waiting_time[sorted_processes[i
- 1]]

# Calculate turnaround time for each process


for i in range(n):
turnaround_time[i] = burst_time[i] + waiting_time[i]

# Generate simplified timeline


timeline.append(processes[sorted_processes[0]])
for i in range(1, n):
if processes[sorted_processes[i]] !=
processes[sorted_processes[i - 1]]:
timeline.append(processes[sorted_processes[i]])

return waiting_time, turnaround_time, timeline

def print_table(processes, burst_time, waiting_time, turnaround_time):


print("Process\tBurst Time\tWaiting Time\tTurnaround Time")
for i in range(len(processes)):
print(f"P{processes[i]}\t{burst_time[i]}\t\t{waiting_time[i]}\
t\t{turnaround_time[i]}")

# Example usage:
processes = [1, 2, 3, 4]
burst_time = [8, 6, 1, 9]
priority = [3, 1, 2, 4]

waiting_time, turnaround_time, timeline =


priority_non_preemptive(processes, burst_time, priority)
print("Priority Scheduling (Non-preemptive) Waiting Time:",
waiting_time)
print("Priority Scheduling (Non-preemptive) Turnaround Time:",
turnaround_time)

# Print Simplified Gantt Chart


print("\nSimplified Gantt Chart:")
print("-" * 30)
print("|", end="")
prev_process = timeline[0]
for process in timeline:
if process != prev_process:
print(f" P{prev_process} |", end="")
prev_process = process
print(f" P{prev_process} |", end="")
print("\n" + "-" * 30)
print("|", end="")
for i in range(len(timeline)):
print(f" {i:2d} |", end="")
print("\n" + "-" * 30)
# Print table of processes, burst time, waiting time, and turnaround
time
print("\nProcess Table:")
print_table(processes, burst_time, waiting_time, turnaround_time)

OUTPUT:
1. Write a program to simulate all File Organization Techniques
a. Single level directory
class SingleLevelDirectory:
def __init__(self):
self.directory = {}

def add_file(self, file_name, file_type):


if file_type not in self.directory:
self.directory[file_type] = []
self.directory[file_type].append(file_name)

def list_files(self):
for file_type, files in self.directory.items():
print(f"{file_type}:")
for file_name in files:
print(f" - {file_name}")

# Create an instance of SingleLevelDirectory


directory = SingleLevelDirectory()

# Add files to the directory


directory.add_file("essay.docx", "Documents")
directory.add_file("report.pdf", "Documents")
directory.add_file("vacation.jpg", "Images")
directory.add_file("family_photo.png", "Images")
directory.add_file("calculator.exe", "Programs")
directory.add_file("text_editor.exe", "Programs")

# List all files in the directory


print("Files in Single-Level Directory:")
directory.list_files()

Output:

b. Two Level
class TwoLevelDirectory:
def __init__(self):
self.directory = {}

def add_file(self, file_name, directory_name):


if directory_name not in self.directory:
self.directory[directory_name] = []
self.directory[directory_name].append(file_name)

def list_files(self):
for directory_name, files in self.directory.items():
print(f"{directory_name}:")
for file_name in files:
print(f" - {file_name}")

# Create an instance of TwoLevelDirectory


directory = TwoLevelDirectory()
# Add files to the directory
directory.add_file("essay.docx", "Documents")
directory.add_file("report.pdf", "Documents")
directory.add_file("vacation.jpg", "Images")
directory.add_file("family_photo.png", "Images")
directory.add_file("calculator.exe", "Programs")
directory.add_file("text_editor.exe", "Programs")

# List all files in the directory


print("Files in Two-Level Directory:")
directory.list_files()

Output:

c. Tree-Structured Directories
class Directory:
def __init__(self, name):
self.name = name
self.subdirectories = {}
self.files = []

def add_file(self, file_name):


self.files.append(file_name)
def add_subdirectory(self, directory_name):
if directory_name not in self.subdirectories:
self.subdirectories[directory_name] =
Directory(directory_name)
return self.subdirectories[directory_name]

def list_contents(self, indent=0):


print(" " * indent + self.name + "/")
for file_name in self.files:
print(" " * (indent + 1) + "- " + file_name)
for subdirectory in self.subdirectories.values():
subdirectory.list_contents(indent + 1)

# Create the root directory


root = Directory("Root")

# Add files directly to the root directory


root.add_file("essay.docx")
root.add_file("report.pdf")

# Create subdirectories and add files to them


documents = root.add_subdirectory("Documents")
documents.add_file("vacation.jpg")
documents.add_file("family_photo.png")

programs = root.add_subdirectory("Programs")
programs.add_file("calculator.exe")
programs.add_file("text_editor.exe")

# List contents of the root directory


print("Contents of Hierarchical Directory:")
root.list_contents()

Output:

d. Acyclic-Graph Directories
class File:
def __init__(self, name):
self.name = name
self.children = []

def add_child(self, child_file):


self.children.append(child_file)

def list_contents(self, indent=0):


print(" " * indent + self.name)
for child in self.children:
child.list_contents(indent + 1)

# Create files
file1 = File("File1")
file2 = File("File2")
file3 = File("File3")
file4 = File("File4")
file5 = File("File5")

# Build DAG structure


file1.add_child(file2)
file1.add_child(file3)
file2.add_child(file4)
file3.add_child(file5)

# List contents
print("Contents of DAG Directory:")
file1.list_contents()

Output:
2. Write a program to simulate all file allocation strategies
a. Contiguous allocation
Dk
class ContiguousAllocation:
def __init__(self, total_blocks):
self.total_blocks = total_blocks
self.disk = [None] * total_blocks

def allocate_file(self, file_name, start_block, num_blocks):


for i in range(start_block, start_block + num_blocks):
if self.disk[i] is not None:
print(f"Error: Block {i} is already allocated.")
return False
for i in range(start_block, start_block + num_blocks):
self.disk[i] = file_name
return True

def deallocate_file(self, file_name):


for i in range(self.total_blocks):
if self.disk[i] == file_name:
self.disk[i] = None

def display_disk_status(self):
print("Disk Status:")
for i, block in enumerate(self.disk):
if block is None:
print(f"Block {i}: Free")
else:
print(f"Block {i}: Allocated to {block}")

# Create an instance of ContiguousAllocation with 20 blocks


allocation = ContiguousAllocation(20)

# Allocate files
allocation.allocate_file("file1", 2, 3)
allocation.allocate_file("file2", 8, 4)

# Display disk status after allocation


allocation.display_disk_status()

# Deallocate file1
allocation.deallocate_file("file1")

# Display disk status after deallocation


allocation.display_disk_status()
b. Indexed
class IndexedAllocation:
def __init__(self, total_blocks):
self.total_blocks = total_blocks
self.disk = [None] * total_blocks
self.index_table = {}

def allocate_file(self, file_name, num_blocks):


if len(self.index_table) >= self.total_blocks:
print("Error: Not enough space on disk.")
return False

if file_name in self.index_table:
print(f"Error: File '{file_name}' already exists.")
return False

allocated_blocks = []
for i in range(num_blocks):
free_block = self._find_free_block()
if free_block is None:
print("Error: Not enough contiguous space on disk.")
self._deallocate_blocks(allocated_blocks)
return False
allocated_blocks.append(free_block)
self.disk[free_block] = file_name

self.index_table[file_name] = allocated_blocks
return True

def deallocate_file(self, file_name):


if file_name not in self.index_table:
print(f"Error: File '{file_name}' not found.")
return False

allocated_blocks = self.index_table[file_name]
self._deallocate_blocks(allocated_blocks)
del self.index_table[file_name]
return True

def _find_free_block(self):
for i in range(self.total_blocks):
if self.disk[i] is None:
return i
return None

def _deallocate_blocks(self, blocks):


for block in blocks:
self.disk[block] = None

def display_disk_status(self):
print("Disk Status:")
for i, block in enumerate(self.disk):
if block is None:
print(f"Block {i}: Free")
else:
print(f"Block {i}: Allocated to {block}")
print("Index Table:")
for file_name, allocated_blocks in self.index_table.items():
print(f"{file_name}: {allocated_blocks}")
# Create an instance of IndexedAllocation with 10 blocks
allocation = IndexedAllocation(10)

# Allocate files
allocation.allocate_file("file1", 3)
allocation.allocate_file("file2", 2)
allocation.allocate_file("file3", 4)

# Display disk status after allocation


allocation.display_disk_status()

# Deallocate file2
allocation.deallocate_file("file2")

# Display disk status after deallocation


allocation.display_disk_status()
c. Linked
class DiskBlock:
def __init__(self, block_number):
self.block_number = block_number
self.next_block = None

class LinkedAllocation:
def __init__(self, total_blocks):
self.total_blocks = total_blocks
self.disk = [None] * total_blocks
self.free_blocks = set(range(total_blocks))

def allocate_file(self, file_name, num_blocks):


if len(self.free_blocks) < num_blocks:
print("Error: Not enough space on disk.")
return False

if file_name in self.disk:
print(f"Error: File '{file_name}' already exists.")
return False

head_block = None
prev_block = None
for i in range(num_blocks):
free_block = self.free_blocks.pop()
self.disk[free_block] = file_name
current_block = DiskBlock(free_block)
if prev_block:
prev_block.next_block = current_block
else:
head_block = current_block
prev_block = current_block

self.disk[file_name] = head_block
return True

def deallocate_file(self, file_name):


if file_name not in self.disk:
print(f"Error: File '{file_name}' not found.")
return False

head_block = self.disk[file_name]
current_block = head_block
while current_block:
self.free_blocks.add(current_block.block_number)
self.disk[current_block.block_number] = None
current_block = current_block.next_block

del self.disk[file_name]
return True

def display_disk_status(self):
print("Disk Status:")
for i, block in enumerate(self.disk):
if isinstance(block, DiskBlock):
print(f"Block {block.block_number}: Allocated to
{self.disk[block.block_number]}")
else:
print(f"Block {i}: Free")
# Create an instance of LinkedAllocation with 10 blocks
allocation = LinkedAllocation(10)

# Allocate files
allocation.allocate_file("file1", 3)
allocation.allocate_file("file2", 2)
allocation.allocate_file("file3", 4)

# Display disk status after allocation


allocation.display_disk_status()

# Deallocate file2
allocation.deallocate_file("file2")

# Display disk status after deallocation


allocation.display_disk_status()
Simulate paging technique of memory management

Let's implement a basic simulation of memory paging with the following


components:

1. Page Table: A data structure to map virtual pages to physical


frames.

2. Memory Management Unit (MMU): Simulates the translation of


virtual addresses to physical addresses using the page table.

3. Page Replacement Algorithm: We'll use a simple FIFO (First In,


First Out) algorithm for replacing pages when there's a page
fault.

class PageTable:
def __init__(self, size):
self.size = size
self.table = {}
self.free_frames = list(range(size)) # Initialize free frames
def page_fault_handler(self, virtual_page):
if virtual_page in self.table:
# Page is already in memory, return corresponding frame
return self.table[virtual_page]
else:
# Page fault: Page is not in memory, allocate a frame
if len(self.free_frames) > 0:
frame = self.free_frames.pop(0) # Get a free frame
self.table[virtual_page] = frame # Map virtual page
to frame
return frame
else:
raise Exception("Out of memory: Cannot handle page
fault")
class MemoryManagementUnit:
def __init__(self, page_table):
self.page_table = page_table

def translate_address(self, virtual_address):


virtual_page = virtual_address // PAGE_SIZE
offset = virtual_address % PAGE_SIZE
try:
frame = self.page_table.page_fault_handler(virtual_page)
physical_address = frame * PAGE_SIZE + offset
return physical_address
except Exception as e:
print(f"Error: {e}")
return None
class Simulation:
def __init__(self, memory_size, page_size):
self.memory_size = memory_size
self.page_size = page_size
self.num_frames = memory_size // page_size
self.page_table = PageTable(self.num_frames)
self.mmu = MemoryManagementUnit(self.page_table)
def access_memory(self, virtual_address):
physical_address = self.mmu.translate_address(virtual_address)
if physical_address is not None:
print(f"Accessing virtual address {virtual_address} ->
Physical address {physical_address}")
def display_page_table(self):
print("Page Table:")
for virtual_page, frame in
sorted(self.page_table.table.items()):
print(f"Virtual Page {virtual_page} -> Frame {frame}")
print(f"Free Frames: {self.page_table.free_frames}")
# Constants
MEMORY_SIZE = 1024 # Total memory size in bytes
PAGE_SIZE = 128 # Page size in bytes
# Initialize simulation
sim = Simulation(MEMORY_SIZE, PAGE_SIZE)
# Access virtual memory addresses
addresses = [0, 256, 512, 100, 384, 768, 512]
for address in addresses:
sim.access_memory(address)
# Display page table after accessing addresses
sim.display_page_table()

You might also like