예제 #1
0
/*************************************************************
************ 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;
}
예제 #3
0
// 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