void BufferManager::selectOneTuple(char * tuple, int size, long position) { cout << "----------------Selecting----------------" << endl; if (getFreeSpaceInCurrentPage(position) > size) { read(tuple, getPageNumber(position), getPagePosition(position), size); } else { int firstSegmentSize = getFreeSpaceInCurrentPage(position); read(tuple, getPageNumber(position), getPagePosition(position), firstSegmentSize); size -= firstSegmentSize; position += firstSegmentSize; tuple += firstSegmentSize; while (size > PAGE_SIZE) { int firstSegmentSize = getFreeSpaceInCurrentPage(position); read(tuple, getPageNumber(position), getPagePosition(position), firstSegmentSize); size -= firstSegmentSize; position += firstSegmentSize; tuple += firstSegmentSize; } read(tuple, getPageNumber(position), getPagePosition(position), size); } cout << "----------------Selecting----------------" << endl; }
// need to insert into list on same page as buffer void insertIntoFreeList(void* buffer, int bufferSize) { int freeBufferIndex = getFreeBufferIndex(bufferSize); void** freeBufferList = getFreeBufferPointer(freeBufferIndex); bufferData_t* currentBuffer = (bufferData_t*)*freeBufferList; bufferData_t* pastBuffer = NULL; // handle case where list is empty if (currentBuffer == NULL) { *freeBufferList = buffer; currentBuffer = (bufferData_t*)*freeBufferList; assert(currentBuffer != NULL); currentBuffer->nextFreeBuffer = NULL; currentBuffer->bufferSize = bufferSize; return; } // now handle case where there are elements in free list size_t inputBufferPage = getPageNumber(BASEADDR(buffer)); size_t currentPageNum = getPageNumber(BASEADDR(currentBuffer)); assert(currentBuffer != NULL); while (currentBuffer->nextFreeBuffer != NULL && currentPageNum < inputBufferPage) { pastBuffer = currentBuffer; currentBuffer = currentBuffer->nextFreeBuffer; assert(currentBuffer != NULL); currentPageNum = getPageNumber(BASEADDR(currentBuffer)); } if (currentBuffer->nextFreeBuffer == NULL) { // reached end of list, insert at end currentBuffer->nextFreeBuffer = buffer; currentBuffer = (bufferData_t*)buffer; currentBuffer->nextFreeBuffer = NULL; currentBuffer->bufferSize = bufferSize; } else { // in middle of list but past where we want to input buffer if (pastBuffer == NULL) { // we want to insert buffer at start of free list *freeBufferList = buffer; ((bufferData_t*)buffer)->nextFreeBuffer = (void*)currentBuffer; ((bufferData_t*)buffer)->bufferSize = bufferSize; } else { // we want to insert list between pastBuffer and currentBuffer assert(pastBuffer != NULL); pastBuffer->nextFreeBuffer = buffer; ((bufferData_t*)buffer)->nextFreeBuffer = (void*)currentBuffer; ((bufferData_t*)buffer)->bufferSize = bufferSize; } } }
int fifo(int* arr, int size) { int pages_size=MEM_SIZE/PAGE_SIZE; PAGE* pages=(PAGE*)malloc(sizeof(PAGE)*pages_size); int fault_count=0; int victim_frame=0; memset(pages,-1,sizeof(PAGE)*pages_size); int i; for(i=0; i<size; i++) { int frame_num=arr[i]/1024; #ifdef ADDR_DEBUG fprintf(stdout,"Logical Address: %i\n",arr[i]); fprintf(stdout,"Frame number: %d\n",getPageNumber(arr[i])); fprintf(stdout,"Before frame number: %d\n",frame_num); #endif if(!isexist(pages, pages_size, frame_num)) { fault_count++; pages[victim_frame].page_num=frame_num; pages[victim_frame].recently_used=0; victim_frame++; if(victim_frame>pages_size) { victim_frame=0; } } } free(pages); return fault_count; }
bool WPSPageSpan::operator==(shared_ptr<WPSPageSpan> const &page2) const { if (!page2) return false; if (page2.get() == this) return true; if (m_formLength < page2->m_formLength || m_formLength > page2->m_formLength || m_formWidth < page2->m_formWidth || m_formWidth > page2->m_formWidth || m_formOrientation != page2->m_formOrientation) return false; if (getMarginLeft()<page2->getMarginLeft() || getMarginLeft()>page2->getMarginLeft() || getMarginRight()<page2->getMarginRight() || getMarginRight()>page2->getMarginRight() || getMarginTop()<page2->getMarginTop() || getMarginTop()>page2->getMarginTop() || getMarginBottom()<page2->getMarginBottom() || getMarginBottom()>page2->getMarginBottom()) return false; if (getPageNumberPosition() != page2->getPageNumberPosition()) return false; if (getPageNumber() != page2->getPageNumber()) return false; if (getPageNumberingType() != page2->getPageNumberingType()) return false; if (getPageNumberingFontName() != page2->getPageNumberingFontName() || getPageNumberingFontSize() < page2->getPageNumberingFontSize() || getPageNumberingFontSize() > page2->getPageNumberingFontSize()) return false; size_t numHF = m_headerFooterList.size(); size_t numHF2 = page2->m_headerFooterList.size(); for (size_t i = numHF; i < numHF2; i++) { if (page2->m_headerFooterList[i]) return false; } for (size_t i = numHF2; i < numHF; i++) { if (m_headerFooterList[i]) return false; } if (numHF2 < numHF) numHF = numHF2; for (size_t i = 0; i < numHF; i++) { if (!m_headerFooterList[i]) { if (page2->m_headerFooterList[i]) return false; continue; } if (!page2->m_headerFooterList[i]) return false; if (*m_headerFooterList[i] != page2->m_headerFooterList[i]) return false; } WPS_DEBUG_MSG(("WordPerfect: WPSPageSpan == comparison finished, found no differences\n")); return true; }
void alterBitMap(void* ptr, int sizeInBytes, bool setBits) { BYTE byteValue; if (setBits) { byteValue = 255; } else { byteValue = 0; } // get base addr of page void* startOfPage = BASEADDR(ptr); size_t pageNumber = getPageNumber(startOfPage); assert(pageNumber >= 0); int numBitsInBitmap = sizeInBytes/MIN_BUFFER_SIZE; size_t bitmapIndex = getByteIndex(startOfPage, ptr); size_t bitmapOffset = getByteOffset(startOfPage, ptr); BYTE* bitmapLoc = &startOfManagedMemory->pages[pageNumber].bitmap[bitmapIndex]; int i; if (bitmapOffset == 0) { // if offset is 0 then possible that we can set bytes at a time for (i=0; i < numBitsInBitmap/8; i++) { *bitmapLoc = byteValue; bitmapLoc = bitmapLoc + 1; } } // if there is a offset within a byte, then we know numBitsInBitmap < 8 because buffer has offset multiples of size assert(bitmapOffset < 8); for (i=bitmapOffset; i < numBitsInBitmap % 8; i++) { if (setBits) { *bitmapLoc |= 1 << (7-i); printf("bitmap altered %hhu\n", *bitmapLoc); } else { *bitmapLoc &= ~(1 << (7-i)); } } }
//read the file in for the opt algorithm //also stores future uses of the pages in the future array. void readOptFile(struct memRef **memList, struct nextUse **future, const char *fileName) { FILE *inFile; //file pointer bit32 tempRef, i = 0; //reference read from file and loop control char tempMode; //read/write mode read from file struct memRef *curr; //current reference being read struct nextUse *futureUse; //used to add this read to future use //open the file inFile = fopen(fileName, "r"); //read the memory references from the file - store in linked list //memList points to the start of the list *memList = (struct memRef *) malloc(sizeof(struct memRef)); (*memList)->next = NULL; curr = *(memList); while(fscanf(inFile, "%x %c", &tempRef, &tempMode) == 2) { struct memRef *temp = (struct memRef *) malloc(sizeof(struct memRef)); bit32 pageNo = getPageNumber(tempRef); temp->reference = tempRef; temp->mode = tempMode; curr->next = temp; curr = curr->next; futureUse = *(future + pageNo); if(futureUse->tail == NULL) { //first instance of this page - create node but no data. don't need to store the first instance futureUse->time = i; futureUse->next = NULL; futureUse->tail = futureUse; } else { futureUse->tail->next = (struct nextUse *) malloc(sizeof(struct nextUse)); futureUse->tail = futureUse->tail->next; futureUse->tail->time = i; futureUse->tail->next = NULL; futureUse->tail->tail = NULL; //tail only used for first node in the list, all other tails can be NULL } i++; } //remove first node of memList - bit sloppy but it works curr = *(memList); *memList = curr->next; free(curr); //close the file fclose(inFile); }
void kma_free(void* ptr, kma_size_t size) { void* internalPtr = (void*)(((BYTE*) ptr) - sizeof(bufferData_t)); int bufferSize = getAmountOfMemoryToRequest(size); size_t pageNum = getPageNumber(BASEADDR(internalPtr)); // unset bitmap unsetBitmap(internalPtr, bufferSize); // coalesce free buddies coalesceFreeMemory(&internalPtr, &bufferSize); if (bufferSize == PAGESIZE) { // can free page free_page(startOfManagedMemory->pages[pageNum].pageData); // right way would be to shift all pages after this over int pageIndex = pageNum + 1; while (startOfManagedMemory->pages[pageIndex].pageData != NULL) { memcpy((void*)&startOfManagedMemory->pages[pageIndex-1], (void*)&startOfManagedMemory->pages[pageIndex], sizeof(pageControlStruct_t*)); pageIndex = pageIndex + 1; } // so that the last page in list isn't duplicated startOfManagedMemory->pages[pageIndex-1].pageData = NULL; int j; for (j=0; j < BITMAP_SIZE; j++) { startOfManagedMemory->pages[pageIndex-1].bitmap[j] = 0; } } if (onlyControlStructureLeft()) { // everything gone except control structure // free page free_page(startOfManagedMemory->pages[0].pageData); startOfManagedMemory = NULL; return; } if (bufferSize != PAGESIZE) { // insert into free list insertIntoFreeList(internalPtr, bufferSize); } }
bool checkIfBitmapSet(void* ptr, int sizeInBytes) { void* startOfPage = BASEADDR(ptr); size_t pageNumber = getPageNumber(startOfPage); assert(pageNumber >= 0); int numBitsInBitmap = sizeInBytes/MIN_BUFFER_SIZE; size_t bitmapIndex = getByteIndex(startOfPage, ptr); size_t bitmapOffset = getByteOffset(startOfPage, ptr); BYTE* bitmapLoc = &startOfManagedMemory->pages[pageNumber].bitmap[bitmapIndex]; int i; if (bitmapOffset == 0) { // if offset is 0 then possible that we can set bytes at a time for (i=0; i < numBitsInBitmap/8; i++) { if (*bitmapLoc != 0) { return TRUE; } bitmapLoc = bitmapLoc + 1; } } // if there is a offset within a byte, then we know numBitsInBitmap < 8 because buffer has offset multiples of size assert(bitmapOffset < 8); for (i=bitmapOffset; i < numBitsInBitmap % 8; i++) { if ((*bitmapLoc & 1 << (7-i)) != 0) { return TRUE; } } // bitmap all 0s, can coalesce! return FALSE; }
string DBSystem::getRecord(string tableName, int recordId) { int pgNo,startRecord; struct Page* newPage; pgNo = getPageNumber(tableName,recordId); string error(""); if( pgNo==-1) return (error); if(pageMemoryHash[pgNo] == NULL){ //cout<<"MISS "; newPage = createNewPage(tableName, pgNo); /*if(currentMemory->count<numberOfPages) //cout<<newPage->frameNumber<<"\n"; else if(currentMemory->rear) //cout<<currentMemory->rear->frameNumber<<"\n"; else //cout<<"\n"; */ lruPageReplace(pgNo,newPage); pageMemoryHash[pgNo] = newPage; } else{ //cout<<"HIT\n"; newPage = pageMemoryHash[pgNo]; placePageInFront(newPage); } startRecord = pageToRecordMap[pgNo].first; string temp= newPage->pageRecords->at(recordId-startRecord); if(temp.at(temp.length()-1)=='\n') temp=temp.substr(0,temp.length()-1); return temp; }
void EditFiles::viewFile(OovStringRef const fn, int lineNum) { FilePath fp; fp.getAbsolutePath(fn, FP_File); auto iter = std::find_if(mFileViews.begin(), mFileViews.end(), [fp](std::unique_ptr<ScrolledFileView> const &fv) -> bool { return fv->mFilename.comparePaths(fp) == 0; }); if(iter == mFileViews.end()) { GtkNotebook *book = nullptr; if(putInMainWindow(fn)) book = mSourceBook; else book = mHeaderBook; if(book) { GtkWidget *scrolled = gtk_scrolled_window_new(nullptr, nullptr); GtkWidget *editView = gtk_text_view_new(); /// @todo - use make_unique when supported. ScrolledFileView *scrolledView = new ScrolledFileView(mDebugger); scrolledView->mFileView.init(GTK_TEXT_VIEW(editView), this); OovStatus status = scrolledView->mFileView.openTextFile(fp); if(status.needReport()) { OovString err = "Unable to open file "; err += fp; status.report(ET_Error, err); } scrolledView->mScrolled = GTK_SCROLLED_WINDOW(scrolled); scrolledView->mFilename = fp; gtk_container_add(GTK_CONTAINER(scrolled), editView); Gui::appendPage(book, scrolled, newTabLabel(fp.getName(), scrolledView->getViewTopParent())); gtk_widget_show_all(scrolled); scrolledView->mLeftMargin.setupMargin(GTK_TEXT_VIEW(editView)); // Set up the windows to draw the line numbers in the left margin. // GTK has changed, and different setups are required for different // versions of GTK. // This is not allowed for a text view // gtk_widget_set_app_paintable(editView, true); #if(USE_DRAW_LAYER) overrideDrawLayer(editView); // If the left window is not created, errors display, "Attempt to // convert text buffer coordinates to coordinates for a nonexistent // buffer or private child window of GtkTextView". So create a // window that is only one pixel wide, and draw the line numbers // on the main text view window. gtk_text_view_set_border_window_size(GTK_TEXT_VIEW(editView), GTK_TEXT_WINDOW_LEFT, 1); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(editView), scrolledView->mLeftMargin.getMarginWidth()); #else // The margin is drawn on the border window. gtk_text_view_set_border_window_size(GTK_TEXT_VIEW(editView), GTK_TEXT_WINDOW_LEFT, scrolledView->mLeftMargin.getMarginWidth()); g_signal_connect(editView, "draw", G_CALLBACK(onTextViewDraw), scrolledView); #endif g_signal_connect(editView, "focus_in_event", G_CALLBACK(on_EditFiles_focus_in_event), NULL); g_signal_connect(editView, "key_press_event", G_CALLBACK(on_EditFiles_key_press_event), NULL); g_signal_connect(editView, "button_press_event", G_CALLBACK(on_EditFiles_button_press_event), NULL); mFileViews.push_back(std::unique_ptr<ScrolledFileView>(scrolledView)); #if(DBG_EDITF) sDbgFile.printflush("viewFile count %d, line %d\n", mFileViews.size(), lineNum); #endif iter = mFileViews.end()-1; } } GtkNotebook *notebook = (*iter)->getBook(); if(notebook) { int pageIndex = getPageNumber(notebook, (*iter)->getTextView()); Gui::setCurrentPage(notebook, pageIndex); // focus is set after the screen is displayed by onIdle // gtk_widget_grab_focus(GTK_WIDGET((*iter).getTextView())); #if(DBG_EDITF) sDbgFile.printflush("viewFile %d\n", pageIndex); #endif if(lineNum > 1) { (*iter)->mDesiredLine = lineNum; } } }
//run the aging simulation void simulateAging(bit32 numFrames, const char *fileName, bit32 refresh) { struct agingFrame *frames; //memory frames struct memRef *memList, *curr; //pointer to the current memory reference bit32 *pageTable; //page table bit32 numRefs = 0, numFaults = 0, numWrites = 0; //stat counters bit32 i, pageNo; //current page number and loop control bit32 usedFrames = 0; //used frames - for compulsory misses //set up page table and ensure all bits are 0 pageTable = (bit32 *) malloc(NUM_PAGES * sizeof(bit32)); memset(pageTable, 0, sizeof(bit32) * NUM_PAGES); //set up the memory frames frames = (struct agingFrame *) malloc(numFrames * sizeof(struct agingFrame)); for(i = 0; i < numFrames; i++) { frames[i].pageNo = ZERO; frames[i].age = 0; } //read the file in and store the references and future uses of the references readFile(&memList, fileName); curr = memList; while(curr != NULL) { //if we have hit the end of the refresh period, shift the ref bit in to the age of each frame //also unreference each frame if(numRefs % refresh == 0) { for(i = 0; i < numFrames; i++) { frames[i].age = frames[i].age >> 1; if(isRef(pageTable, frames[i].pageNo)) { frames[i].age = frames[i].age | AGING_REF; } pageTable[frames[i].pageNo] = pageTable[frames[i].pageNo] & CLEAR_REF; } } pageNo = getPageNumber(curr->reference); if(isValid(pageTable, pageNo)) { //page already already valid/in a frame - hit pageHitSetBits(pageTable, pageNo, curr->mode); //set appropriate bits printf("%i\thit\n", numRefs + 1); } else { //page is not in frame yet - miss numFaults++; //compulsory miss - will only happen numFrames times if(usedFrames < numFrames) { frames[usedFrames].pageNo = pageNo; //store the page number in the frame //update the page table entry placePageInFrame(pageTable, pageNo, usedFrames, curr->mode); //map current page to frame usedFrames++; printf("%i\tpage fault - no eviction\n", numRefs + 1); } else { //capacity miss - frames are full and page is not in a frame - will need to evict bit32 oldestFrame = 0; unsigned short int min = NINE_BITS; for(i = 0; i < numFrames; i++) { //find the oldest frame unsigned short int age = frames[i].age; if(isRef(pageTable, frames[i].pageNo)) { //if page is referenced, shift on the 9th bit age = age | AGING_REF; } if(age < min) { oldestFrame = i; min = age; } } //ends for //evict the oldest frame if(isDirty(pageTable, frames[oldestFrame].pageNo)) { numWrites++; printf("%i\tpage fault - evict dirty\n", numRefs + 1); } else { printf("%i\tpage fault - evict clean\n", numRefs + 1); } evictPage(pageTable, frames[oldestFrame].pageNo); frames[oldestFrame].pageNo = pageNo; //store the page number in the frame //update the page table entry placePageInFrame(pageTable, pageNo, oldestFrame, curr->mode); //map current page to frame } } //increment number of references and move to next reference numRefs++; curr = curr->next; } //print stats printf("\nAging\n"); printf("Number of frames:\t%i\n", numFrames); printf("Total memory accesses:\t%i\n", numRefs); printf("Total page faults:\t%i\n", numFaults); printf("Total writes to disk:\t%i\n\n", numWrites); //clean up memory free(frames); }
//run the NRU algorithm simulation void simulateNRU(bit32 numFrames, const char *fileName, bit32 refresh) { bit32 *frames; //list of frames bit32 *pageTable; //page table bit32 numFaults = 0, numWrites = 0, numRefs = 0; //stat counters bit32 usedFrames = 0, pageNo, i; //number of frames used and the page number, loop counter struct memRef *memList, *curr; //pointer to current memory reference //set up page table and ensure all bits are 0 pageTable = (bit32 *) malloc(NUM_PAGES * sizeof(bit32)); memset(pageTable, 0, sizeof(bit32) * NUM_PAGES); //set up the memory frames frames = (bit32 *) malloc(numFrames * sizeof(bit32)); //seed the random number generator srand(time(NULL)); //read the file in and store the references and future uses of the references readFile(&memList, fileName); curr = memList; while(curr != NULL) { //if we've hit the refresh mark, mark all pages unreferenced if((numRefs % refresh) == 0) { for(i = 0; i < usedFrames; i++) { pageTable[frames[i]] = pageTable[frames[i]] & CLEAR_REF; } } pageNo = getPageNumber(curr->reference); if(isValid(pageTable, pageNo)) { //page already already valid/in a frame - hit pageHitSetBits(pageTable, pageNo, curr->mode); //set appropriate bits printf("%i\thit\n", numRefs + 1); } else { //page is not in a frame yet - miss numFaults++; //compulsory miss - will only happen numFrames times if(usedFrames < numFrames) { frames[usedFrames] = pageNo; //store the page number in the frame placePageInFrame(pageTable, pageNo, usedFrames, curr->mode); //map current page to frame usedFrames++; printf("%i\tpage fault - no eviction\n", numRefs + 1); } else { //capacity miss - frames are full and page is not in a frame - will need to evict bit32 frameToEvict = -1; bit32 *cleanUnref, *dirtyUnref, *cleanRef; //stores the indicies of each class of eviction candidate bit32 numCleanUnref = 0, numDirtyUnref = 0, numCleanRef = 0; //stores the number of candidates in each class //set up eviction candidate arrays cleanUnref = (bit32 *) malloc(sizeof(bit32) * numFrames); dirtyUnref = (bit32 *) malloc(sizeof(bit32) * numFrames); cleanRef = (bit32 *) malloc(sizeof(bit32) * numFrames); //find the number and place of each eviction candidate for(i = 0; i < numFrames; i++) { if(!isRef(pageTable, frames[i]) && !isDirty(pageTable, frames[i])) { //page in current frame is not referenced and not dirty cleanUnref[numCleanUnref] = i; numCleanUnref++; } else if(!isRef(pageTable, frames[i]) && isDirty(pageTable, frames[i])) { //page in current frame is not referenced, but is dirty - second best solution dirtyUnref[numDirtyUnref] = i; numDirtyUnref++; } else if(isRef(pageTable, frames[i]) && !isDirty(pageTable, frames[i])) { //page is referenced, but not dirty - third best solution cleanRef[numCleanRef] = i; numCleanRef++; } } if(numCleanUnref > 0) { //choose random number i = rand() % numCleanUnref; frameToEvict = cleanUnref[i]; } else if(numDirtyUnref > 0) { //choose random number i = rand() % numDirtyUnref; frameToEvict = dirtyUnref[i]; } else if(numCleanRef > 0) { //choose random number i = rand() % numCleanRef; frameToEvict = cleanRef[i]; } else { //all frames were referenced and dirty - choose any random frame frameToEvict = rand() % numFrames; } //free memory of arrays - frame to evict has been found free(cleanUnref); free(dirtyUnref); free(cleanRef); //evict the frame if(isDirty(pageTable, frames[frameToEvict])) { numWrites++; printf("%i\tpage fault - evict dirty\n", numRefs + 1); } else { printf("%i\tpage fault - evict clean\n", numRefs + 1); } evictPage(pageTable, frames[frameToEvict]); frames[frameToEvict] = pageNo; //store the page number in the frame placePageInFrame(pageTable, pageNo, frameToEvict, curr->mode); //map current page to frame } } //increment number of references and move to next reference numRefs++; curr = curr->next; } //ends while //print stats printf("\nNRU\n"); printf("Number of frames:\t%i\n", numFrames); printf("Total memory accesses:\t%i\n", numRefs); printf("Total page faults:\t%i\n", numFaults); printf("Total writes to disk:\t%i\n\n", numWrites); //clean up memory free(frames); } //ends NRU simulation
//run the OPT algorithm simulation void simulateOpt(bit32 numFrames, const char *fileName) { struct memRef *memList, *curr; //list of memory references bit32 *pageTable; //page table struct nextUse **future; //array of nextUse structures struct nextUse *tempFuture; //used to deallocate nodes of future use bit32 numFaults = 0, numWrites = 0, numRefs = 0; //stat counters struct optFrame *frames; //frame structure bit32 i, pageNo, frameNo, usedFrames = 0; //loop control, page number, frame number, and number of used frames //set up page table and ensure all bits are 0 pageTable = (bit32 *) malloc(NUM_PAGES * sizeof(bit32)); memset(pageTable, 0, sizeof(bit32) * NUM_PAGES); //set up the future array future = (struct nextUse **) malloc(sizeof(struct nextUse *) * NUM_PAGES); for(i = 0; i < NUM_PAGES; i++) { struct nextUse *temp = (struct nextUse *) malloc(sizeof(struct nextUse)); temp->time = MAX_UINT; temp->next = NULL; temp->tail = NULL; *(future + i) = temp; } //read the file in and store the references and future uses of the references readOptFile(&memList, future, fileName); //set up memory frames frames = (struct optFrame *) malloc(sizeof(struct optFrame) * numFrames); for(i = 0; i < numFrames; i++) { frames[i].pageNo = MAX_UINT; frames[i].next = *(future + i); } curr = memList; while(curr != NULL) { pageNo = getPageNumber(curr->reference); if(isValid(pageTable, pageNo)) { //page already already valid/in a frame - hit pageHitSetBits(pageTable, pageNo, curr->mode); //set appropriate bits frameNo = getFrameNumber(pageTable, pageNo); //get the frame number for this page tempFuture = future[pageNo]; //store current use for deallocation future[pageNo] = future[pageNo]->next; //move the next use down one frames[frameNo].next = future[pageNo]; //update the future array with next use of this page free(tempFuture); //deallocate printf("%i\thit\n", numRefs + 1); } else { //page is not in a frame yet - miss numFaults++; //compulsory miss - will only happen numFrames times if(usedFrames < numFrames) { frames[usedFrames].pageNo = pageNo; //store the page number in the frame tempFuture = future[pageNo]; //store current use for deallocation future[pageNo] = future[pageNo]->next; //move the next use of this page down frames[usedFrames].next = future[pageNo]; //update the link to future use in the frame table free(tempFuture); //deallocate the current use placePageInFrame(pageTable, pageNo, usedFrames, curr->mode); //map current page to frame usedFrames++; printf("%i\tpage fault - no eviction\n", numRefs + 1); } else { //capacity miss - evict page not used until furthest in future bit32 furthest = 0; //index of the page with the furthest future use bit32 ptIndex; //page number of the page used furthest in the future i = 0; if(frames[i].next == NULL) { //there is not future use of this page - we were lucky, can avoid loop furthest = i; } else { for(i = 1; i < numFrames; i++) { if(frames[i].next == NULL) { //there is no future use of this page - can safely remove furthest = i; //printf("\tNULL FOUND: furthest = %i", furthest); i = numFrames; //exit loop } else { //find the furthest future use of a page if(frames[i].next->time > frames[furthest].next->time) { furthest = i; } } } } //evict page in frame[furthest] - page used furthest in future ptIndex = frames[furthest].pageNo; if(isDirty(pageTable, ptIndex)) { numWrites++; printf("%i\tpage fault - evict dirty\n", numRefs + 1); } else { printf("%i\tpage fault - evict clean\n", numRefs + 1); } evictPage(pageTable, ptIndex); frames[furthest].pageNo = pageNo; //store the page number in the frame tempFuture = future[pageNo]; //store current use for deallocation future[pageNo] = future[pageNo]->next; //move future use down to next use frames[furthest].next = future[pageNo]; //update the frames reference to the future table free(tempFuture); //deallocate memory placePageInFrame(pageTable, pageNo, furthest, curr->mode); //map current page to frame } } //increment number of references and move to next reference numRefs++; curr = curr->next; } //print stats printf("\nNRU\n"); printf("Number of frames:\t%i\n", numFrames); printf("Total memory accesses:\t%i\n", numRefs); printf("Total page faults:\t%i\n", numFaults); printf("Total writes to disk:\t%i\n\n", numWrites); //clean up memory free(frames); free(future); }
void BufferManager::deleteOneTuple(int size, long position) { cout << "----------------Deleting----------------" << endl; if (getFreeSpaceInCurrentPage(position) > size) { char * temp = (char *)malloc(size * sizeof(char)); for (int i = 0; i < size; i++) temp[i] = '\0'; write(temp, getPageNumber(position), getPagePosition(position), size); setFileHeader(getPageNumber(position), 0); free(temp); } else { //More than one segment //First segment int firstSegmentSize = getFreeSpaceInCurrentPage(position); char * temp = (char *)malloc(firstSegmentSize * sizeof(char)); for (int i = 0; i < firstSegmentSize; i++) temp[i] = '\0'; cout << "Delete segment. Start PageNumber: " << getPageNumber(position) << " PagePosition: " << getPagePosition(position) << " Size: " << firstSegmentSize << endl; write(temp, getPageNumber(position), getPagePosition(position), firstSegmentSize); setFileHeader(getPageNumber(position), 0); size -= firstSegmentSize; position += firstSegmentSize; free(temp); //Second to last second segments temp = (char *)malloc(PAGE_SIZE * sizeof(char)); for (int i = 0; i < PAGE_SIZE; i++) temp[i] = '\0'; while (size > PAGE_SIZE) { write(temp, getPageNumber(position), getPagePosition(position), PAGE_SIZE); cout << "Delete segment. Start PageNumber: " << getPageNumber(position) << " PagePosition: " << getPagePosition(position) << " Size: " << PAGE_SIZE << endl; setFileHeader(getPageNumber(position), 0); size -= PAGE_SIZE; position += PAGE_SIZE; } free(temp); //last segment temp = (char *)malloc(size * sizeof(char)); for (int i = 0; i < size; i++) temp[i] = '\0'; write(temp, getPageNumber(position), getPagePosition(position), size); cout << "Delete segment. Start PageNumber: " << getPageNumber(position) << " PagePosition: " << getPagePosition(position) << " Size: " << size << endl; setFileHeader(getPageNumber(position), 0); free(temp); } cout << "----------------Deleting----------------" << endl; }
long BufferManager::insertOneTuple(char * tuple, int size) { DBFileManager * dBFileManager = DBFileManager::getInstance(); cout << "----------------Finding free space----------------" << endl; long insertPosition = findFreeSpace(size); long returnPosition = insertPosition; if (insertPosition == -1) { long fileLength = dBFileManager->length(); if (fileLength < MAX_PAGE_NUM * PAGE_SIZE) { insertPosition = fileLength; } else { cout << "Out of max size of DB File." << endl; exit(0); } } cout << "Find the enough free space from position:'" << insertPosition << "'." << endl; cout << "----------------Finding free space----------------" << endl; cout << "----------------Inserting----------------" << endl; if (getFreeSpaceInCurrentPage(insertPosition) > size) { //Just one segment cout << "Just one segment. PageNumber: " << getPageNumber(insertPosition) << " PagePosition: " << getPagePosition(insertPosition) << " Size: " << (getFreeSpaceInCurrentPage(insertPosition)) << "." << endl; write(tuple, getPageNumber(insertPosition), getPagePosition(insertPosition), size); if (isPageWritable(getPageNumber(insertPosition)) == false) setFileHeader(getPageNumber(insertPosition), 1); } else { //More than one segment //First segment cout << "More than one segment. " << endl; cout<<"Insert first segment. Start PageNumber: " << getPageNumber(insertPosition) << " PagePosition: " << getPagePosition(insertPosition) << " Size: " << getFreeSpaceInCurrentPage(insertPosition) << "." << endl; write(tuple, getPageNumber(insertPosition), getPagePosition(insertPosition), getFreeSpaceInCurrentPage(insertPosition)); if (isPageWritable(getPageNumber(insertPosition)) == false) setFileHeader(getPageNumber(insertPosition), 1); size -= (PAGE_SIZE - getPagePosition(insertPosition)); tuple += (PAGE_SIZE - getPagePosition(insertPosition)); insertPosition += (PAGE_SIZE - getPagePosition(insertPosition)); //Second to last second segments while (size > PAGE_SIZE) { cout << "Insert segment. Start PageNumber: " << getPageNumber(insertPosition) << " PagePosition: " << getPagePosition(insertPosition) << " Size: " << PAGE_SIZE << endl; write(tuple, getPageNumber(insertPosition), getPagePosition(insertPosition), PAGE_SIZE); setFileHeader(getPageNumber(insertPosition), 1); size -= PAGE_SIZE; tuple += PAGE_SIZE; insertPosition += PAGE_SIZE; } //last segment cout << "Insert segment. Start PageNumber: " << getPageNumber(insertPosition) << " PagePosition: " << getPagePosition(insertPosition) << " Size: " << size << endl; write(tuple, getPageNumber(insertPosition), getPagePosition(insertPosition), size); if (isPageWritable(getPageNumber(insertPosition)) == false) setFileHeader(getPageNumber(insertPosition), 1); } cout << "----------------Inserting----------------" << endl; return returnPosition; }
LINE_ANALYSIS_RESULT treatLine ( char IN OUT *line, char IN *previousLine, int OUT *page) /* * find out whether the line: * - start a new comment (START_COMMENT): the p, page, etc. keyword are at * the beginning * - is a text line or a blank line that shall be copied to output (COPY), * - is a "---..." line or an extra blank line and shall be not copied (SKIP) * * REMARK: input line can be modified (blank lines are purged of blanks * and tabs) */ /* * REMARK: This the routine has multiple exits!!!! */ { int i = 0; /* index & counter */ int p = 0; /* page number */ int length = 0; /* input string length */ /* * Is it a blank line following a previous blank line? * --------------------------------------------------- * To check this the line is first purged of blanks and tabs and * if the resultant length is 0 the line is compared with the previous line */ length = strlen(line); i = length; while ( i >=0 ) /* starting from the end, */ { /* blanks and tabs are skipped */ if ( (line[i] == ' ' ) || (line[i] == '\t' ) ) length--; i--; } if (length == 0) line[0] = '\0'; if (length == 0) { if (strlen(previousLine) == 0) { return SKIP; } else { return COPY; } } else { /* perform the following checks */ } /* * Is it a "---..." line? * ---------------------- * To check this the first three characters are checked. */ if ((line[0] == '-') && (line[1] == '-') && (line[2] == '-')) { line[0] = '\0'; return SKIP; } /* * Is it the start of a comment? * ----------------------------- * A line is the beginning of a comment if the first non-blank char is a "p" * or "P" followed by alphabetic chars and by a number, optionally separated * by "." or blanks. * So, first the existence of "p" or "P" the beginning of the line is checked. * If a keyword is found then the number is decoded, if possible. */ length = strlen(line); i = 0; while ((line[i] == ' ' ) || /* skip heading blanks and tabs */ (line[i] == '\t' )) { i++; } if ((line[i] == 'p' ) || /* to be a comment must have P or p */ (line[i] == 'P' )) { p = getPageNumber(line, i); /* get page number, if any */ if (p >=0) { *page = p; return START_COMMENT; } } else { /* perform the following checks */ } /* * If none of the previous cases, copy it: */ return COPY; }
//run the clock simulation void simulateClock(bit32 numFrames, const char *fileName) { struct clockFrame *frames, *currFrame; //pointers to the frame list and the current frame bit32 *pageTable; //page table struct memRef *memList, *currRef; //pointer to current memory reference bit32 numFaults = 0, numWrites = 0, numRefs = 0; //stat counters bit32 usedFrames = 0, pageNo, i; //number of used frames, loop counter //set up page table and ensure all bits are 0 pageTable = (bit32 *) malloc(NUM_PAGES * sizeof(bit32)); memset(pageTable, 0, sizeof(bit32) * NUM_PAGES); //set up the frame clock for(i = 0; i < numFrames; i++) { struct clockFrame *temp = (struct clockFrame *) malloc(sizeof(struct clockFrame)); temp->frameNo = i; temp->pageNo = ZERO; temp->next = NULL; if(i == 0) { frames = temp; //if its the first time through, we've created the first frame } else { currFrame->next = temp; //if it's not the first, temp frame should be pointed to by previous frame } currFrame = temp; //update curr } currFrame->next = frames; currFrame = frames; //read the file in and store the references and future uses of the references readFile(&memList, fileName); currRef = memList; while(currRef != NULL) { pageNo = getPageNumber(currRef->reference); if(isValid(pageTable, pageNo)) { //page already valid/in a frame - hit pageHitSetBits(pageTable, pageNo, currRef->mode); //set appropriate bits printf("%i\thit\n", numRefs + 1); } else { //page is not in a frame yet - miss numFaults++; if(usedFrames < numFrames) { //compulsory miss - add the page to the next frame currFrame->pageNo = pageNo; currFrame = currFrame->next; placePageInFrame(pageTable, pageNo, currFrame->frameNo, currRef->mode); //map current page to frame usedFrames++; printf("%i\tpage fault - no eviction\n", numRefs + 1); } else { //capacity miss - frames are full and page is not in a frame - will need to evict //find an unreferenced page, clearing referenced pages along the way while(isRef(pageTable, currFrame->pageNo)) { pageTable[currFrame->pageNo] = pageTable[currFrame->pageNo] & CLEAR_REF; currFrame = currFrame->next; } //currFrame now points to an unreferenced page - evict the frame if(isDirty(pageTable, currFrame->pageNo)) { numWrites++; printf("%i\tpage fault - evict dirty\n", numRefs + 1); } else { printf("%i\tpage fault - evict clean\n", numRefs + 1); } evictPage(pageTable, currFrame->pageNo); currFrame->pageNo = pageNo; //store the page number in the frame placePageInFrame(pageTable, pageNo, currFrame->frameNo, currRef->mode); //map current page to frame //move curr to the next frame currFrame = currFrame->next; } } //increment number of references and move to next reference numRefs++; currRef = currRef->next; } //print stats printf("\nClock\n"); printf("Number of frames:\t%i\n", numFrames); printf("Total memory accesses:\t%i\n", numRefs); printf("Total page faults:\t%i\n", numFaults); printf("Total writes to disk:\t%i\n\n", numWrites); //clean up memory currFrame = frames; for(i = 0; i < numFrames; i++) { frames = currFrame->next; free(currFrame); currFrame = frames; } } //ends clock simulation