diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b9862e1..f8f0ed9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,22 +1,22 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/alpine -{ - "name": "Alpine", - // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "image": "mcr.microsoft.com/devcontainers/base:alpine-3.20" - - // Features to add to the dev container. More info: https://containers.dev/features. - // "features": {}, - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - - // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "uname -a", - - // Configure tool-specific properties. - // "customizations": {}, - - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. - // "remoteUser": "root" -} +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/alpine +{ + "name": "Alpine", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/base:alpine-3.20" + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "uname -a", + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/a.out b/a.out index c3bb602..de4ad49 100644 Binary files a/a.out and b/a.out differ diff --git a/hw4.c b/hw4.c index 087445d..aa263a0 100644 --- a/hw4.c +++ b/hw4.c @@ -1,169 +1,177 @@ -// HW4 -// Nicholas Pease -#include -#include - -//Globals -#define PAGE_SIZE 256 -#define PHYSICAL_PAGE_COUNT 64 -#define LOGICAL_PAGE_COUNT 256 - -#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n" -#define BYTE_TO_BINARY(byte) \ - ((byte) & 32768 ? '1' : '0'), \ - ((byte) & 16384 ? '1' : '0'), \ - ((byte) & 8192 ? '1' : '0'), \ - ((byte) & 4096 ? '1' : '0'), \ - ((byte) & 2048 ? '1' : '0'), \ - ((byte) & 1024 ? '1' : '0'), \ - ((byte) & 512 ? '1' : '0'), \ - ((byte) & 256 ? '1' : '0'), \ - ((byte) & 0x80 ? '1' : '0'), \ - ((byte) & 0x40 ? '1' : '0'), \ - ((byte) & 0x20 ? '1' : '0'), \ - ((byte) & 0x10 ? '1' : '0'), \ - ((byte) & 0x08 ? '1' : '0'), \ - ((byte) & 0x04 ? '1' : '0'), \ - ((byte) & 0x02 ? '1' : '0'), \ - ((byte) & 0x01 ? '1' : '0') - -typedef enum { false, true } bool; - -int numPageFaults = 0; - -struct MemoryAddress { - unsigned short int address; - unsigned int pageNumber; - unsigned int offset; - unsigned int runNumber; // Run Number -}; - -struct PageTableEntry { - int pageNumber; // Physical Page Number - bool valid; // Valid bit defaults to false (page not loaded) -}; - -struct PageTableEntry RAMTracker[PHYSICAL_PAGE_COUNT]; // Physical RAM Tracker -struct PageTableEntry LogicalRAMTracker[LOGICAL_PAGE_COUNT]; // Logical RAM Tracker -unsigned char RAM[PHYSICAL_PAGE_COUNT][PAGE_SIZE] = {[0 ... 63] = {[0 ... 255] = 0}}; // RAM initialized to 0s -unsigned short int addresses[512]; // Randomly generated logical addresses -int leastRecentlyUsedCalculation[PHYSICAL_PAGE_COUNT] = { [0 ... 63] = 0 }; // LRU calculation array - -// Methods for VirtualMemory - -struct MemoryAddress generateAddress(unsigned short int logicalAddress, unsigned int runNumber) { - unsigned short int offsetbitMask = 0b0000000011111111; - struct MemoryAddress generatedAddress; - // 16 bits for address ( 8 page, 8 offset) - generatedAddress.address = logicalAddress; // Set the logical address - generatedAddress.pageNumber = logicalAddress >> 8; // Moves 8 to the left (leaving page) - generatedAddress.offset = logicalAddress & offsetbitMask; // Applies the bitmask to get the offset - generatedAddress.runNumber = runNumber; // Set the run number - - return generatedAddress; -} - -int LRU() { - printf("No Free Page Frame. Invoking LRU Page Replacement Algorithm\n"); - for (int j = 0; j < 64, j++;) { - printf("Testing"); - }; - return 1; - // // Find the least recently used page - // int oldestPage = 0; - // for (int i = 1; i < PHYSICAL_PAGE_COUNT; i++) { - // if (leastRecentlyUsedCalculation[i] < oldestPage && oldestPage == 0) { - // oldestPage = i; // Update the oldest page - // } else if (oldestPage == 0 && leastRecentlyUsedCalculation[i] != 0) { - // oldestPage = i; // If zero, set to the current if not also 0 - // } - // } - // printf("Victim Physical Page is %d\n", oldestPage); - // printf("LP %d is currently mapped to victim page frame\n", RAMTracker[oldestPage].pageNumber); - // return oldestPage; // Return the page number of the least recently used page -} - -void loadIntoRAM(unsigned int logicalPageNumber) { - // Determine if there is a free page in RAM - int physicalPageNumber = -1; - for (int i = 0; i < PHYSICAL_PAGE_COUNT; i++) { - if (RAMTracker[i].valid == false) { - physicalPageNumber = i; // Found a free page - printf("Found Free Frame %d in memory\n", physicalPageNumber); - break; - } - } - - // If no free page, find "victim" page using LRU algorithm - if (physicalPageNumber == -1) physicalPageNumber = LRU(); - - // Load from file into RAM using the free page number - FILE *fp = fopen("Back.bin", "rb"); // Open file for reading - unsigned char buf[256][PAGE_SIZE]; - for (int i = 0; i < 256; i++) fread(buf[i], PAGE_SIZE, 1, fp); // Write 256 pages - - fclose(fp); // Close file - - // Update RAM and RAMTracker - for (int i = 0; i < PAGE_SIZE; i++) { - RAM[physicalPageNumber][i] = buf[logicalPageNumber][i]; // Load the page into RAM - } - - RAMTracker[physicalPageNumber].valid = true; // Set the page as valid - RAMTracker[physicalPageNumber].pageNumber = logicalPageNumber; - LogicalRAMTracker[logicalPageNumber].valid = true; // Set the logical page as valid - LogicalRAMTracker[logicalPageNumber].pageNumber = physicalPageNumber; - - printf("Logical Page %d Now Mapped to Physical Page %d\n", logicalPageNumber, physicalPageNumber); -} - -void readFromAddress(struct MemoryAddress logicalAddress) { - // Check if page is already loaded into RAM - if (LogicalRAMTracker[logicalAddress.pageNumber].valid != true) { - // Page is not loaded into RAM, so we need to calculate and load it - numPageFaults++; - printf("Page Not Mapped. Page Fault Number %d.\n", numPageFaults); - loadIntoRAM(logicalAddress.pageNumber); // Load the page into RAM - } - - int physicalPageNumber = LogicalRAMTracker[logicalAddress.pageNumber].pageNumber; // Get the physical page number - - // Add to LRU list - leastRecentlyUsedCalculation[physicalPageNumber] = logicalAddress.runNumber; // Update the LRU calculation with the current run number - - // Page confirmed to be in RAM, so we can read from it - printf("Final address is Physical Page: %d Offset: %d\n", physicalPageNumber, logicalAddress.offset); // Print the final address - char data = RAM[physicalPageNumber][logicalAddress.offset]; // Read the data from RAM - printf("The value at that address: %d\n", data); // Print the data -} - -main(int argc, char *argv[]) -{ - srand(9); // all get same addresses - struct MemoryAddress logicalAddress; - - for (int i = 0; i < 512; i++) addresses[i] = rand() % 65535; // Logical Address Generation - - //Generate File Contents - unsigned char buf[256]; // Contents of a page - for (int i = 0; i < 256; i++) buf[i] = (unsigned char)i; // Fill with 0-255 - FILE *fp = fopen("Back.bin", "wb"); // Open file for writing - for (int i = 0; i < 256; i++) fwrite(buf, 256, 1, fp); // Write 256 pages - fclose(fp); // Close file - //End Generate File Contents - - for (int i = 0; i < 100; i++) - { - logicalAddress = generateAddress(addresses[i], i); // Generate the address via the struct - printf("Reference %d. Logical Address %d\n", i, logicalAddress.address); // Print the logical address - printf("Logical Page %d, Offset %d\n", logicalAddress.pageNumber, logicalAddress.offset); // Print the page number and offset - // printf("Address: "BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(logicalAddress.address)); - // printf("Page Bits: "BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(logicalAddress.pageNumber)); - // printf("Offset Bits: "BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(logicalAddress.offset)); - - readFromAddress(logicalAddress); // Read from the address (and perform memory operations if required)) - printf("\n"); - } - - return 0; +// HW4 +// Nicholas Pease +#include +#include + +//Globals +#define PAGE_SIZE 256 +#define PHYSICAL_PAGE_COUNT 64 +#define LOGICAL_PAGE_COUNT 256 + +typedef enum { false, true } bool; + +int numPageFaults = 0; + +struct MemoryAddress { + unsigned short int address; + unsigned int pageNumber; + unsigned int offset; + unsigned int runNumber; // Run Number +}; + +struct PageTableEntry { + int pageNumber; // Physical Page Number + bool valid; // Valid bit defaults to false (page not loaded) +}; + +struct PageTableEntry RAMTracker[PHYSICAL_PAGE_COUNT]; // Physical RAM Tracker +struct PageTableEntry LogicalRAMTracker[LOGICAL_PAGE_COUNT]; // Logical RAM Tracker +unsigned char RAM[PHYSICAL_PAGE_COUNT][PAGE_SIZE] = {[0 ... 63] = {[0 ... 255] = 0}}; // RAM initialized to 0s +unsigned short int addresses[512]; // Randomly generated logical addresses +int leastRecentlyUsedCalculation[PHYSICAL_PAGE_COUNT] = { [0 ... 63] = 0 }; // LRU calculation array + +// Methods for VirtualMemory + +struct MemoryAddress generateAddress(unsigned short int logicalAddress, unsigned int runNumber) { + unsigned short int offsetbitMask = 0b0000000011111111; + struct MemoryAddress generatedAddress; + // 16 bits for address ( 8 page, 8 offset) + generatedAddress.address = logicalAddress; // Set the logical address + generatedAddress.pageNumber = logicalAddress >> 8; // Moves 8 to the left (leaving page) + generatedAddress.offset = logicalAddress & offsetbitMask; // Applies the bitmask to get the offset + generatedAddress.runNumber = runNumber; // Set the run number + + return generatedAddress; +} + +int LRU() { + // Find the least recently used page + + // Start at 0 and work down + int oldestPage = 0; // Initialize the oldest page to 0 + int oldestRunNumber = leastRecentlyUsedCalculation[0]; // Initialize the oldest run number + for (int i = 1; i < PHYSICAL_PAGE_COUNT; i++) { + if (leastRecentlyUsedCalculation[i] < oldestRunNumber) { + oldestPage = i; // Update the oldest page + oldestRunNumber = leastRecentlyUsedCalculation[i]; // Update the oldest run number + } + } + printf("Victim Physical Page is %d\n", oldestPage); + printf("LP %d is currently mapped to victim page frame\n", RAMTracker[oldestPage].pageNumber); + // Update logical RAM tracker + LogicalRAMTracker[RAMTracker[oldestPage].pageNumber].valid = false; // Set the logical page as valid + LogicalRAMTracker[RAMTracker[oldestPage].pageNumber].pageNumber = 0; + return oldestPage; // Return the page number of the least recently used page +} + +void loadIntoRAM(unsigned int logicalPageNumber) { + // Determine if there is a free page in RAM + int physicalPageNumber = -1; + for (int i = 0; i < PHYSICAL_PAGE_COUNT; i++) { + if (RAMTracker[i].valid == false) { + physicalPageNumber = i; // Found a free page + printf("Found Free Frame %d in memory\n", physicalPageNumber); + break; + } + } + + // If no free page, find "victim" page using LRU algorithm + if (physicalPageNumber == -1) physicalPageNumber = LRU(); + + // Load from file into RAM using the free page number + FILE *fp = fopen("Back.bin", "rb"); // Open file for reading + unsigned char buf[256]; + fseek(fp, logicalPageNumber * PAGE_SIZE, SEEK_SET); // Move to target page + fread(buf, PAGE_SIZE, 1, fp); // Pull out page from the file + fclose(fp); // Close file + + // Update RAM + for (int i = 0; i < PAGE_SIZE; i++) { + RAM[physicalPageNumber][i] = buf[i]; // Load the page into RAM + } + + RAMTracker[physicalPageNumber].valid = true; // Set the page as valid + RAMTracker[physicalPageNumber].pageNumber = logicalPageNumber; + LogicalRAMTracker[logicalPageNumber].valid = true; // Set the logical page as valid + LogicalRAMTracker[logicalPageNumber].pageNumber = physicalPageNumber; + + printf("Logical Page %d Now Mapped to Physical Page %d\n", logicalPageNumber, physicalPageNumber); +} + +void readFromAddress(struct MemoryAddress logicalAddress) { + // Check if page is already loaded into RAM + if (LogicalRAMTracker[logicalAddress.pageNumber].valid != true) { + // Page is not loaded into RAM, so we need to calculate and load it + numPageFaults++; + printf("Page Not Mapped. Page Fault Number %d.\n", numPageFaults); + loadIntoRAM(logicalAddress.pageNumber); // Load the page into RAM + } else { + printf("Logical Page %d is in memory and mapped to Physical Page %d\n", logicalAddress.pageNumber, LogicalRAMTracker[logicalAddress.pageNumber].pageNumber); + } + + int physicalPageNumber = LogicalRAMTracker[logicalAddress.pageNumber].pageNumber; // Get the physical page number + + // Add to LRU list + leastRecentlyUsedCalculation[physicalPageNumber] = logicalAddress.runNumber; // Update the LRU calculation with the current run number + + // Page confirmed to be in RAM, so we can read from it + printf("Final address is Physical Page: %d Offset: %d\n", physicalPageNumber, logicalAddress.offset); // Print the final address + unsigned char data = RAM[physicalPageNumber][logicalAddress.offset]; // Read the data from RAM + printf("The value at that address: %d\n", data); // Print the data +} + +void finalOutput() { + printf("Final Output:\n"); + printf("%d Total Page Faults\n", numPageFaults); + + for (int i = 0; i < LOGICAL_PAGE_COUNT; i++) { + if (LogicalRAMTracker[i].valid) { printf("Logical Page %d Mapped to Physical Page %d\n", i, LogicalRAMTracker[i].pageNumber); } + else { printf("Logical Page %d Not Mapped\n", i); } + } + + printf("\n\n"); + printf("State of Physical RAM:\n"); + printf("Address = Row * 16 + Column (in Hex)\n"); + printf("I.E: F (15) * 16 + F (15) = 255\n"); + for (int col = 0; col < 16; col++) printf("\t%X", col); + printf("\n"); + for (int row = 0; row < 16; row++) { + printf("%X \t", row); + for (int col = 0; col < 16; col++) { + int index = row * 16 + col; + if (LogicalRAMTracker[index].valid) { + printf("%d \t", LogicalRAMTracker[index].pageNumber); + } else { + printf(" \t"); // X for not mapped + } + } + printf("\n"); + } +} + +main(int argc, char *argv[]) +{ + srand(9); // all get same addresses + for (int i = 0; i < 512; i++) addresses[i] = rand() % 65535; // Logical Address Generation + + // Generate File Contents + unsigned char buf[256]; // Contents of a page + for (int i = 0; i < 256; i++) buf[i] = (unsigned char)i; // Fill with 0-255 + FILE *fp = fopen("Back.bin", "wb"); // Open file for writing + for (int i = 0; i < 256; i++) fwrite(buf, 256, 1, fp); // Write 255 pages + fclose(fp); // Close file + //End Generate File Contents + + for (int i = 0; i < 512; i++) + { + struct MemoryAddress logicalAddress = generateAddress(addresses[i], i); // Generate the address via the struct + printf("Reference %d. Logical Address %d\n", i, logicalAddress.address); // Print the logical address + printf("Logical Page %d, Offset %d\n", logicalAddress.pageNumber, logicalAddress.offset); // Print the page number and offset + readFromAddress(logicalAddress); // Read from the address (and perform memory operations if required)) + printf("\n"); + } + + finalOutput(); + + return 0; } \ No newline at end of file