#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; } 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 (frames[leastRecentlyUsedIndex].dirty) { pagesSwapped++; } return leastRecentlyUsedIndex; } 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; } 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); } 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 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 0; }