/************************************************************* ************ LRU-CLOCK Page Replacement Algorithm ************ *************************************************************/ void LRUClockPageReplacement(){ int numberOfPageFaults = 0; frame = malloc(sizeof(struct frames)); head = malloc(sizeof(struct frames)); tail = malloc(sizeof(struct frames)); head = frame; tail = frame; clock = frame; frame->next = NULL; frame->prev = head; frame->pageNum = inputSeq[0]; frame->refBit = 1; numberOfPageFaults += 1; int i, isPageAlreadyExists = 0; for (i=1; i<strlen(inputSeq); i++){ if (isspace(inputSeq[i]) == 0){ isPageAlreadyExists = findPage(inputSeq[i]); if (isPageAlreadyExists == 1){ toggleRefBitForExistingPage(inputSeq[i]); }else if (isPageAlreadyExists == 0 && isFrameAvailable() == 1){ numberOfPageFaults += 1; framesLeft -= 1; addPageToTailOfFrame(inputSeq[i]); }else if (isPageAlreadyExists == 0 && isFrameAvailable() == 0){ numberOfPageFaults += 1; iterateClock(); replacePage(inputSeq[i]); } } } printf("\n# of page replacements with LRU-CLOCK = %d\n",numberOfPageFaults-availableFrames); nbOfPageReplacementByAlgo = numberOfPageFaults-availableFrames; }
/************************************************************************************** * Function Name: FIFO * * Description: * FIFO replacement strategy * * Parameters: * BM_BufferPool * const bm: Buffer Pool Handler * BM_PageHandle * const page: Buffer Page Handler * PageNumber pageNum: the page number of the requested page * * Return: * RC: return code * * Author: * Xin Su <*****@*****.**> * * History: * Date Name Content * ---------- ---------------------------------- ------------------------ * 2015-03-15 Xin Su <*****@*****.**> Initialization. **************************************************************************************/ RC FIFO(BM_BufferPool * const bm, BM_PageHandle * const page, PageNumber pageNum) { // First search the page in the queue RC rc = -99; // init return code rc = searchPage(bm, page, pageNum); // If find the page, then simply return RC_OK if (rc != RC_PAGE_NOT_FOUND) { return rc; } /* * If the code comes here, then the Buffer Manager doesn't have the page loaded. * We have to read the page from the disk and load it into BM_PageHandle. */ PageList *queue = (PageList *) bm->mgmtData; // If the Buffer Manager has vacancy for the requested page, // then read the page from the disk and append it to the tail of the PageList if (queue->size < bm->numPages) { rc = -99; // reset return code rc = appendPage(bm, page, pageNum); return rc; } /* * If the code comes here, then neither the Buffer Manager has the page loaded nor has vacancy for the requested page. * The size of the PageList = bm->numPages * We have to replace an existing page in the Buffer Manager with the requested page. */ // Find the first removable page, starting from head // Set the current pointer to the head of the queue to start the traversal queue->current = queue->head; while (queue->current != queue->tail && queue->current->fixCount != 0) { queue->current = queue->current->next; } // After the while loop, if the current pointer comes to the tail // then we still need to determine if the tail's fixCount = 0 if (queue->current == queue->tail && queue->current->fixCount != 0) { return RC_NO_REMOVABLE_PAGE; } /* * If the code comes here, then a removable page is found, and the current pointer is pointing to it */ // Replace the removable page with the requested page rc = -99; // reset the return value rc = replacePage(bm, page, pageNum); return rc; }
// pins the page with page number given RC pinPage (BM_BufferPool *const bm, BM_PageHandle *const page, const PageNumber pageNum){ // check if bm has been initialized if(bm == NULL) return RC_BUFFER_MGR_NOT_INIT; // check if PageNumber passed is a valid one if(pageNum < 0) return RC_INVALID_PAGENUMBER; int frameNum = find(pageNum, bm->mgmtData->hashT); if(frameNum>=0) // page found { page->pageNum = pageNum; page->data = (char *) malloc(PAGE_SIZE);//strlen(bm->mgmtData->hashT->hashArray[frameNum]->pageHandle->data) + 1); memcpy(page->data, bm->mgmtData->hashT->hashArray[frameNum]->pageHandle->data, PAGE_SIZE); // page->data = bm->mgmtData->hashT->hashArray[frameNum]->pageHandle->data; bm->mgmtData->hashT->hashArray[frameNum]->fixCount++; // update the linked list for the page pinned updateList(bm,frameNum); return RC_OK; } else // page not found { // check if empty frames are present if(bm->mgmtData->emptyFrames==0){ // call page replacement function frameNum = replacePage(bm,pageNum); if(frameNum == -1) return RC_NO_FRAME_WAIT; } else { // insert new pageFrame into Hash Table //int frameNum; frameNum = findPageFrame(pageNum,bm->mgmtData->hashT); updatePageFrameList(bm,pageNum,frameNum,true); bm->mgmtData->emptyFrames--; } page->pageNum = pageNum; page->data = (char *) malloc(PAGE_SIZE);//strlen(bm->mgmtData->hashT->hashArray[frameNum]->pageHandle->data) + 1); memcpy(page->data, bm->mgmtData->hashT->hashArray[frameNum]->pageHandle->data, PAGE_SIZE); // page->data = bm->mgmtData->hashT->hashArray[frameNum]->pageHandle->data; return RC_OK; } }
/************************************************************************************** * Function Name: CLOCK * * Description: * CLOCK replacement strategy * * Parameters: * BM_BufferPool * const bm: Buffer Pool Handler * BM_PageHandle * const page: Buffer Page Handler * PageNumber pageNum: the page number of the requested page * * Return: * RC: return code * * Author: * Xin Su <*****@*****.**> * * History: * Date Name Content * ---------- ---------------------------------- ------------------------ * 2015-03-15 Xin Su <*****@*****.**> Initialization. **************************************************************************************/ RC CLOCK(BM_BufferPool * const bm, BM_PageHandle * const page, PageNumber pageNum) { PageList *queue = (PageList *) bm->mgmtData; // First search the page in the queue. RC rc = -99; // init return code rc = searchPage(bm, page, pageNum); // if find the page, set the current page's clockFlag to TRUE // else if other errors happen, return rc if (rc == RC_OK) { queue->current->clockFlag = TRUE; return rc; } else if (rc != RC_PAGE_NOT_FOUND) { return rc; } /* * If the code comes here, then the Buffer Manager doesn't have the page loaded. * We have to read the page from the disk and load it into BM_PageHandle. */ // If the Buffer Manager has vacancy for the requested page, // then read the page from the disk and append it to the tail of the PageList if (queue->size < bm->numPages) { rc = -99; // reset return code rc = appendPage(bm, page, pageNum); if (rc == RC_OK) { // Set the clock pointer to the next to the current pointer // if the PageList is not full, set the clock pointer to the next to the current pointer // else, set the clock pointer to the head if (queue->size < bm->numPages) { queue->clock = queue->current->next; } else if (queue->size == bm->numPages) { queue->clock = queue->head; } } return rc; } /* * If the code comes here, then neither the Buffer Manager has the page loaded nor has vacancy for the requested page. * The size of the PageList = bm->numPages * We have to replace an existing page in the Buffer Manager with the requested page. */ // Logic of CLOCK replacement strategy // Now the current points to should point to the page that was requested last time while (queue->clock->clockFlag != FALSE) { queue->clock->clockFlag = FALSE; if (queue->clock == queue->tail) { queue->clock = queue->head; } else { queue->clock = queue->clock->next; } } // We find the first PageFrame whose clockFlag is FALSE // Set the current pointer to the clock pointer queue->current = queue->clock; /*RC*/rc = -99;// do not need to redefine RC rc = replacePage(bm, page, pageNum); if (rc == RC_OK) { // After the replacement of the requested page, set its clockFlag to TRUE queue->clock->clockFlag = TRUE; // TO DO - Whether we need to set the clock pointer to the next to the current pointer? if (queue->clock == queue->tail) { queue->clock = queue->head; } else { queue->clock = queue->clock->next; } } return rc; }
/************************************************************************************** * Function Name: CLOCK * * Description: * CLOCK replacement strategy * * Parameters: * BM_BufferPool * const bm: Buffer Pool Handler * BM_PageHandle * const page: Buffer Page Handler * PageNumber pageNum: the page number of the requested page * * Return: * RC: return code * * Author: * Xin Su <*****@*****.**> * * History: * Date Name Content * ---------- ---------------------------------- ------------------------ * 2015-03-15 Xin Su <*****@*****.**> Initialization **************************************************************************************/ RC CLOCK(BM_BufferPool * const bm, BM_PageHandle * const page, PageNumber pageNum) { PageList *queue = (PageList *) bm->mgmtData; RC rc; // init return code // First search the page in the PageList printf("searchPage: Page-%d\n", pageNum); rc = -99; rc = searchPage(bm, page, pageNum); // if find the page, set the current page's clockFlag to TRUE // else if other errors happen, return rc if (rc == RC_PAGE_FOUND) { queue->current->fixCount++; queue->current->clockFlag = TRUE; printf("Page-%d found\n", pageNum); return rc; } else if (rc != RC_PAGE_NOT_FOUND) { return rc; } printf("Page-%d not found\n", pageNum); /* * If the code comes here, then the Buffer Manager doesn't have the page loaded. * We have to read the page from the disk and load it into BM_PageHandle. */ // if the Buffer Manager has vacancy for the requested page, // then read the page from the disk and append it to the next to the tail of the PageList if (queue->size < bm->numPages) { printf("appendPage: Page-%d\n", pageNum); rc = -99; // reset return code rc = appendPage(bm, page, pageNum); // if the PageList is not full, set the clock pointer to the next to the current pointer // else, now the current pointer points to the tail, then set the clock pointer points back to the head if (rc == RC_OK) { if (queue->size < bm->numPages) { queue->clock = queue->current->next; } else if (queue->size == bm->numPages) { queue->clock = queue->head; } printf("Page-%d appended\n", pageNum); } return rc; } /* * If the code comes here, then neither the Buffer Manager has the page loaded nor vacancy for the requested page * Now the PageList is full: the size of the PageList = bm->numPages * We have to replace an existing page in the Buffer Manager with the requested page */ // Logic of CLOCK replacement strategy // Now the current pointer points to the page that was requested last time, // and the clock pointer points to the next to the current pointer (or back to the head if the current pointers points to the tail) // Find the first page with clockFlag = TRUE and fixCount = 0 while (queue->clock->clockFlag == TRUE || queue->clock->fixCount != 0 || queue->clock->numReadIO != 0 || queue->clock->numWriteIO != 0) { queue->clock->clockFlag = FALSE; // Into the while loop means this page does not fit the requirement of the removable page // Move the clock pointer to the next. If it points to the tail, move it back to the head if (queue->clock == queue->tail) { queue->clock = queue->head; } else { queue->clock = queue->clock->next; } } // We find the first PageFrame whose clockFlag = FALSE and fixCount = 0 // Set the current pointer to the clock pointer, so that we can call replacePage queue->current = queue->clock; // Replace the removable page with the requested page printf("replacePage: Page-%d\n", pageNum); rc = -99; rc = replacePage(bm, page, pageNum); if (rc == RC_OK) { // After the replacement of the requested page, set its clockFlag to TRUE queue->clock->clockFlag = TRUE; // Set the clock pointer to the next to the current pointer if (queue->clock == queue->tail) { queue->clock = queue->head; } else { queue->clock = queue->clock->next; } printf("Page-%d replaced\n", pageNum); } return rc; } // CLOCK
/************************************************************************************** * Function Name: FIFO * * Description: * FIFO replacement strategy * * Parameters: * BM_BufferPool * const bm: Buffer Pool Handler * BM_PageHandle * const page: Buffer Page Handler * PageNumber pageNum: the page number of the requested page * * Return: * RC: return code * * Author: * Xin Su <*****@*****.**> * * History: * Date Name Content * ---------- ---------------------------------- ------------------------ * 2015-03-15 Xin Su <*****@*****.**> Initialization. **************************************************************************************/ RC FIFO(BM_BufferPool * const bm, BM_PageHandle * const page, PageNumber pageNum) { PageList *queue = (PageList *) bm->mgmtData; RC rc; // init return code // First search the requested page in the PageList printf("searchPage: Page-%d\n", pageNum); rc = -99; rc = searchPage(bm, page, pageNum); // First search the requested page in the queue // if the requested page is found, then set statistics and return rc (RC_PAGE_FOUND) // else if something unexpected error happens, then return rc if (rc == RC_PAGE_FOUND) { queue->current->fixCount++; printf("Page-%d found\n", pageNum); return rc; } else if (rc != RC_PAGE_NOT_FOUND) { return rc; } printf("Page-%d not found\n", pageNum); /* * If the code comes here, then the Buffer Manager doesn't have the requested page * We have to read the page from the disk and load it into BM_PageHandle. */ // if the Buffer Manager has vacancy for the requested page, // then read the page from the disk and append it to the next of the tail of the PageList if (queue->size < bm->numPages) { printf("appendPage: Page-%d\n", pageNum); rc = -99; // reset return code rc = appendPage(bm, page, pageNum); if (rc == RC_OK) { printf("Page-%d appended\n", pageNum); } return rc; } /* * If the code comes here, then neither the Buffer Manager has the requested page loaded nor vacancy for the requested page * Now the PageList is full: the size of the PageList = bm->numPages * We have to replace an existing page in the Buffer Manager with the requested page */ // Find the first removable page, starting from head // Set the current pointer to the head of the queue to start the traversal queue->current = queue->head; // Find the first page with fixCount = 0 while (queue->current != queue->tail && (queue->current->fixCount != 0 || queue->current->numReadIO != 0 || queue->current->numWriteIO != 0)) { queue->current = queue->current->next; } // After the while loop, if the current pointer comes to the tail, // then we still need to determine if the tail's fixCount = 0 if (queue->current == queue->tail && (queue->current->fixCount != 0 || queue->current->numReadIO != 0 || queue->current->numWriteIO != 0)) { return RC_NO_REMOVABLE_PAGE; } /* * If the code comes here, then a removable page is found * The current pointer is pointing to it */ // Replace the removable page with the requested page printf("replacePage: Page-%d\n", pageNum); rc = -99; // reset the return value rc = replacePage(bm, page, pageNum); // if replacePage completes without error and the requested page is not in the tail spot // then move it to the tail of the PageList if (rc == RC_OK && queue->current != queue->tail) { // Remove the current PageFrame // The steps of the remove are different depending on if the requested page is the head or not if (queue->current == queue->head) { queue->head = queue->head->next; queue->current->next->previous = NULL; } else { queue->current->previous->next = queue->current->next; queue->current->next->previous = queue->current->previous; } // Add the requested page to the tail of the PageList // step 1 - connect tail and current queue->current->previous = queue->tail; queue->tail->next = queue->current; // step 2 - set current's next queue->current->next = NULL; // step 3 - set tail queue->tail = queue->tail->next; printf("Page-%d replaced\n", pageNum); // Now the current pointer still points to the requested page } return rc; } // FIFO