Final
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,25 @@
|
||||
COS331
|
||||
HW4
|
||||
Nicholas Pease
|
||||
|
||||
How To Compile
|
||||
Compiling this program is done using gcc as follows
|
||||
gcc hw4.c
|
||||
|
||||
How to Run
|
||||
Run this program by executing the resulting binary
|
||||
./a.out
|
||||
|
||||
Limitations of Program
|
||||
If you want to mess with the page sizes and counts, you should be able to modify these three DEFINES in the homework file to achieve this, but this is untested
|
||||
#define PAGE_SIZE 256
|
||||
#define PHYSICAL_PAGE_COUNT 64
|
||||
#define LOGICAL_PAGE_COUNT 256
|
||||
|
||||
Beyond this, there are no limitations of the program in regards to the assignment. Everything should function as directed.
|
||||
|
||||
Aspects of Program to Improve
|
||||
I think I have already implemented this program to the best of my ability in C. I would love to take it to a object-oirented language like C++ instead, where I could extend the memory management further, but as it stands, this program is fairly modular, allowing easy exchange of the LRU and modification of pseudo-system resources. Perhaps an optimization to not create the bin file if it already exists would be advantageous.
|
||||
|
||||
Sources:
|
||||
fseek (https://www.geeksforgeeks.org/fseek-in-c-with-example/)
|
||||
+104
-57
@@ -3,56 +3,69 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//Globals
|
||||
// Defines
|
||||
#define PAGE_SIZE 256
|
||||
#define PHYSICAL_PAGE_COUNT 64
|
||||
#define LOGICAL_PAGE_COUNT 256
|
||||
|
||||
typedef enum { false, true } bool;
|
||||
// Structs and Enums
|
||||
typedef enum
|
||||
{
|
||||
false,
|
||||
true
|
||||
} bool;
|
||||
|
||||
int numPageFaults = 0;
|
||||
|
||||
struct MemoryAddress {
|
||||
struct MemoryAddress
|
||||
{
|
||||
unsigned short int address;
|
||||
unsigned int pageNumber;
|
||||
unsigned int offset;
|
||||
unsigned int runNumber; // Run Number
|
||||
};
|
||||
|
||||
struct PageTableEntry {
|
||||
struct PageTableEntry
|
||||
{
|
||||
int pageNumber; // Physical Page Number
|
||||
bool valid; // Valid bit defaults to false (page not loaded)
|
||||
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
|
||||
// Globals
|
||||
int numPageFaults = 0;
|
||||
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
|
||||
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) {
|
||||
// Generates a MemoryAddress datatype from the current address, as well as calculates page and offset
|
||||
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.address = logicalAddress; // Set the logical address
|
||||
generatedAddress.pageNumber = logicalAddress >> 8; // Moves 8 to the right (leaving page)
|
||||
generatedAddress.offset = logicalAddress & offsetbitMask; // Applies the bitmask to get the offset
|
||||
generatedAddress.runNumber = runNumber; // Set the run number
|
||||
generatedAddress.runNumber = runNumber; // Set the run number
|
||||
|
||||
return generatedAddress;
|
||||
}
|
||||
|
||||
int LRU() {
|
||||
// Least Recently Used (LRU) Algorithm
|
||||
int LRU()
|
||||
{
|
||||
// Find the least recently used page
|
||||
|
||||
// Start at 0 and work down
|
||||
int oldestPage = 0; // Initialize the oldest page to 0
|
||||
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
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -64,11 +77,16 @@ int LRU() {
|
||||
return oldestPage; // Return the page number of the least recently used page
|
||||
}
|
||||
|
||||
void loadIntoRAM(unsigned int logicalPageNumber) {
|
||||
// Loads a DiskPage into RAM via its logical page number
|
||||
// If there is no free page, it will use the LRU algorithm to find a victim 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) {
|
||||
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;
|
||||
@@ -76,17 +94,22 @@ void loadIntoRAM(unsigned int logicalPageNumber) {
|
||||
}
|
||||
|
||||
// If no free page, find "victim" page using LRU algorithm
|
||||
if (physicalPageNumber == -1) physicalPageNumber = LRU();
|
||||
if (physicalPageNumber == -1)
|
||||
{
|
||||
printf("No Free Page Frame. Invoking LRU Page Replacement Algorithm\n");
|
||||
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];
|
||||
unsigned char buf[PAGE_SIZE];
|
||||
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
|
||||
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++) {
|
||||
for (int i = 0; i < PAGE_SIZE; i++)
|
||||
{
|
||||
RAM[physicalPageNumber][i] = buf[i]; // Load the page into RAM
|
||||
}
|
||||
|
||||
@@ -98,14 +121,20 @@ void loadIntoRAM(unsigned int logicalPageNumber) {
|
||||
printf("Logical Page %d Now Mapped to Physical Page %d\n", logicalPageNumber, physicalPageNumber);
|
||||
}
|
||||
|
||||
void readFromAddress(struct MemoryAddress logicalAddress) {
|
||||
// Outermost method to initiate reading from a specific logical address
|
||||
// Takes a MemoryAddress struct as input
|
||||
void readFromAddress(struct MemoryAddress logicalAddress)
|
||||
{
|
||||
// Check if page is already loaded into RAM
|
||||
if (LogicalRAMTracker[logicalAddress.pageNumber].valid != true) {
|
||||
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 {
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Logical Page %d is in memory and mapped to Physical Page %d\n", logicalAddress.pageNumber, LogicalRAMTracker[logicalAddress.pageNumber].pageNumber);
|
||||
}
|
||||
|
||||
@@ -116,33 +145,49 @@ void readFromAddress(struct MemoryAddress logicalAddress) {
|
||||
|
||||
// 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
|
||||
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);
|
||||
// Final outputs as per homework guidelines
|
||||
// Also outputs as table
|
||||
void finalOutput()
|
||||
{
|
||||
printf("Final Output:\n\n");
|
||||
printf("%d Total Page Faults\n\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); }
|
||||
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("Logical Page Mappings:\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("I.E: F (15) * 16 + F (15) = 255\n\n");
|
||||
for (int col = 0; col < 16; col++)
|
||||
printf("\t%X", col);
|
||||
printf("\n");
|
||||
for (int row = 0; row < 16; row++) {
|
||||
for (int row = 0; row < 16; row++)
|
||||
{
|
||||
printf("%X \t", row);
|
||||
for (int col = 0; col < 16; col++) {
|
||||
for (int col = 0; col < 16; col++)
|
||||
{
|
||||
int index = row * 16 + col;
|
||||
if (LogicalRAMTracker[index].valid) {
|
||||
if (LogicalRAMTracker[index].valid)
|
||||
{
|
||||
printf("%d \t", LogicalRAMTracker[index].pageNumber);
|
||||
} else {
|
||||
printf(" \t"); // X for not mapped
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" \t"); // blank for not mapped
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
@@ -152,25 +197,27 @@ void finalOutput() {
|
||||
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
|
||||
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
|
||||
unsigned char buf[PAGE_SIZE]; // Contents of a page
|
||||
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 < 256; i++)
|
||||
buf[i] = (unsigned char)i; // Fill with 0-255
|
||||
for (int i = 0; i < PAGE_SIZE; i++)
|
||||
fwrite(buf, PAGE_SIZE, 1, fp); // Write 255 pages
|
||||
fclose(fp); // Close file
|
||||
|
||||
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
|
||||
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))
|
||||
readFromAddress(logicalAddress); // Read from the address (and perform memory operations if required))
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
finalOutput();
|
||||
|
||||
return 0;
|
||||
Reference in New Issue
Block a user