#include #include #include #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; }