Untitled
unknown
plain_text
a year ago
3.9 kB
9
Indexable
#include "VirtualMemory.h"
#include "PhysicalMemory.h"
void clearFrame(uint64_t baseAddress) {
for (uint64_t i = 0; i < PAGE_SIZE; i++) {
PMwrite(baseAddress * PAGE_SIZE + i, 0);
}
}
void VMinitialize() {
clearFrame(0);
}
bool isValidAddress(uint64_t virtualAddress) {
if (virtualAddress >= VIRTUAL_MEMORY_SIZE) {
return false;
}
if (TABLES_DEPTH > NUM_FRAMES) {
return false;
}
return true;
}
int translateAddress(uint64_t virtualAddress, word_t* value, bool isWrite);
int VMread(uint64_t virtualAddress, word_t* value) {
if (!isValidAddress(virtualAddress) || value == nullptr) {
return 0;
}
return translateAddress(virtualAddress, value, false);
}
int VMwrite(uint64_t virtualAddress, word_t value) {
if (!isValidAddress(virtualAddress)) {
return 0;
}
return translateAddress(virtualAddress, &value, true);
}
int translateAddress(uint64_t virtualAddress, word_t* value, bool isWrite) {
uint64_t address = virtualAddress;
uint64_t offset = address & (PAGE_SIZE - 1);
uint64_t currentFrame = 0;
for (int depth = 0; depth < TABLES_DEPTH; depth++) {
uint64_t index = (address >> (OFFSET_WIDTH + (TABLES_DEPTH - depth - 1) * OFFSET_WIDTH)) & (PAGE_SIZE - 1);
word_t nextFrame;
PMread(currentFrame * PAGE_SIZE + index, &nextFrame);
if (nextFrame == 0) {
if (!isWrite) {
return 0; // Page fault or address not mapped
}
nextFrame = findFreeFrame(currentFrame, depth);
if (nextFrame == 0) {
return 0; // No free frames available
}
PMwrite(currentFrame * PAGE_SIZE + index, nextFrame);
clearFrame(nextFrame); // Clear the new frame
}
currentFrame = nextFrame;
}
uint64_t physicalAddress = currentFrame * PAGE_SIZE + offset;
if (isWrite) {
PMwrite(physicalAddress, *value);
} else {
PMread(physicalAddress, value);
}
return 1;
}
word_t findFreeFrame(uint64_t currentFrame, int depth) {
bool framesUsed[NUM_FRAMES] = {false};
markUsedFrames(0, framesUsed);
for (uint64_t frame = 1; frame < NUM_FRAMES; frame++) {
if (!framesUsed[frame]) {
return frame;
}
}
word_t frameToEvict = findFrameToEvict();
evictFrame(frameToEvict, currentFrame, depth);
return frameToEvict;
}
void markUsedFrames(uint64_t frame, bool* framesUsed) {
framesUsed[frame] = true;
for (uint64_t i = 0; i < PAGE_SIZE; i++) {
word_t value;
PMread(frame * PAGE_SIZE + i, &value);
if (value != 0) {
markUsedFrames(value, framesUsed);
}
}
}
word_t findFrameToEvict() {
// Implement the eviction policy as described in the assignment.
// This example uses a placeholder policy that evicts the last frame.
// You should replace this with the actual eviction logic.
return NUM_FRAMES - 1;
}
void evictFrame(word_t frame, uint64_t currentFrame, int depth) {
// Implement the logic to evict a frame.
// This should involve writing the frame's contents back to the "disk"
// and clearing its entries in the parent table.
// Find the parent frame and index
uint64_t parentFrame = currentFrame;
uint64_t address = frame * PAGE_SIZE;
for (int d = 0; d < depth - 1; d++) {
uint64_t index = (address >> (OFFSET_WIDTH + (TABLES_DEPTH - d - 1) * OFFSET_WIDTH)) & (PAGE_SIZE - 1);
PMread(parentFrame * PAGE_SIZE + index, &parentFrame);
}
uint64_t index = (address >> OFFSET_WIDTH) & (PAGE_SIZE - 1);
PMwrite(parentFrame * PAGE_SIZE + index, 0); // Set the parent entry to 0
// Clear the frame
PMclear(frame);
}
void PMclear(uint64_t frame) {
for (uint64_t i = 0; i < PAGE_SIZE; i++) {
PMwrite(frame * PAGE_SIZE + i, 0);
}
}
Editor is loading...
Leave a Comment