CS3413/Assignment7/code/main.c

157 lines
4.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define OFFSETBITS 12
#define PAGESIZE (1 << OFFSETBITS)
#define PAGETABLEBITS 10
#define ARCH 32
int framesSize;
unsigned int pageFault = 0;
unsigned int pageHits = 0;
unsigned int pagesSwapped = 0;
int time = 0;
typedef struct frameEntry {
unsigned int pageNumber;
int lastUsed;
bool dirty;
} frameEntry;
frameEntry *frames;
int getPageOffsetAddress(unsigned long logicalAddress) {
// Last 12 bits of logical address
// Page size is 4096 bytes, and we bitwise AND with 4095 (111111111111) to get the last 12 bits
return logicalAddress & (PAGESIZE - 1);
}
int getPageNumber(unsigned long logicalAddress) {
// First 20 bits of logical address
// Bitwise shift right 12 bits to get the first 20 bits, as the last 12 bits are discarded
return logicalAddress >> OFFSETBITS;
}
void printPhysicalAddress(int frameID, unsigned long logicalAddress) {
printf("%lu -> %i\n", logicalAddress, frameID * PAGESIZE + getPageOffsetAddress(logicalAddress));
}
double computeFormula() {
// probabilityOfNoPageFault 10 + probabilityOfMajorPageFaultWithOneCopy 1000 + probabilityOfMajorPageFaultWithTwoCopyOperations 3000
double probabilityOfNoPageFault = 1 - (double) pageFault / (pageFault + pageHits);
double probabilityOfMajorPageFaultWithOneCopy = (double) pageFault / (pageFault + pageHits) * (1 - (double) pagesSwapped / pageFault);
double probabilityOfMajorPageFaultWithTwoCopyOperations = (double) pageFault / (pageFault + pageHits) * (double) pagesSwapped / pageFault;
return probabilityOfNoPageFault * 10 + probabilityOfMajorPageFaultWithOneCopy * 1000 + probabilityOfMajorPageFaultWithTwoCopyOperations * 3000;
}
// Int so we can return the index of the frame if it is in the frames array
int isInFrames(int pageNumber) {
for (int i = 0; i < framesSize; i++) {
if (frames[i].pageNumber == pageNumber) {
return i;
}
}
return -1;
}
// Swap out the least recently used frame
// Returns the index of the frame that was swapped out
int swapOut() {
// Find the least recently used frame
int leastRecentlyUsed = 0x7FFFFFFF;
int leastRecentlyUsedIndex = -1;
for (int i = 0; i < framesSize; i++) {
if (frames[i].lastUsed < leastRecentlyUsed) {
leastRecentlyUsed = frames[i].lastUsed;
leastRecentlyUsedIndex = i;
}
}
// Swap out is implied, so we increment pageSwapped
// If the frame is dirty, we need to write it to disk, so we increment pagesSwapped
if (frames[leastRecentlyUsedIndex].dirty) {
pagesSwapped++;
}
return leastRecentlyUsedIndex;
}
// Swap in a page
// Returns the index of the frame that was swapped in
int swapIn(int pageNumber) {
// Find the first empty frame
for (int i = 0; i < framesSize; i++) {
if (frames[i].pageNumber == -1) {
pageFault++;
frames[i].pageNumber = pageNumber;
return i;
}
}
// If no empty frames, swap out a frame
int frameID = swapOut();
frames[frameID].pageNumber = pageNumber;
pageFault++;
return frameID;
}
// Read from an address
void readFromAddress(unsigned long logicalAddress) {
unsigned int pageNumber = getPageNumber(logicalAddress);
int frameID = isInFrames(pageNumber);
if (isInFrames(pageNumber) == -1) {
frameID = swapIn(pageNumber);
} else {
pageHits++;
}
frames[frameID].lastUsed = time;
printPhysicalAddress(frameID, logicalAddress);
}
// Write to an address, only difference is that we set the dirty bit to true
void writeToAddress(unsigned long logicalAddress) {
unsigned int pageNumber = getPageNumber(logicalAddress);
int frameID = isInFrames(pageNumber);
if (isInFrames(pageNumber) == -1) {
frameID = swapIn(pageNumber);
} else {
pageHits++;
}
frames[frameID].dirty = true;
frames[frameID].lastUsed = time;
printPhysicalAddress(frameID, logicalAddress);
}
int main(int argc, char **argv) {
//Disable printf buffering for easier debugging
setbuf(stdout, NULL);
framesSize = atoi(argv[1]);
frames = calloc(framesSize, sizeof(frameEntry));
// Initialize frames to -1, so we can check if a frame is empty
for (int i = 0; i < framesSize; i++) {
frames[i].pageNumber = -1;
frames[i].lastUsed = -1;
frames[i].dirty = false;
}
unsigned long logicalAddress;
char operation;
printf("Logical addresses -> Physical addresses:\n");
while (EOF != scanf("%c %lu\n", &operation, &logicalAddress)) {
if (operation == 'r') {
readFromAddress(logicalAddress);
} else {
writeToAddress(logicalAddress);
}
time++;
}
printf("\nStats:\nmajor page faults = %u\npage hits = %u\npages swapped out = %u\nEffective Access Time = %.3lf\n",
pageFault,
pageHits,
pagesSwapped,
computeFormula()
);
return EXIT_SUCCESS;
}