/* * Allocates a frame to be used for the virtual page represented by p. * If all frames are in use, calls the replacement algorithm's evict_fcn to * select a victim frame. Writes victim to swap if needed, and updates * pagetable entry for victim to indicate that virtual page is no longer in * (simulated) physical memory. * * Counters for evictions should be updated appropriately in this function. */ int allocate_frame(pgtbl_entry_t *p) { int i; int frame = -1; for(i = 0; i < memsize; i++) { if(!coremap[i].in_use) { frame = i; break; } } if(frame == -1) { // Didn't find a free page. // Call replacement algorithm's evict function to select victim frame = evict_fcn(); // All frames were in use, so victim frame must hold some page // Write victim page to swap, if needed, and update pagetable // IMPLEMENTATION NEEDED // Get the offset and the frame number int swap_offset = (int) coremap[frame].pte->swap_off; // Write the victim page into swap int swap_offset_page = swap_pageout(frame, swap_offset); assert(swap_offset_page != INVALID_SWAP); // Update the coremap coremap[frame].pte->frame = coremap[frame].pte->frame & ~PG_VALID; coremap[frame].pte->swap_off = (off_t) swap_offset_page; coremap[frame].pte->frame = coremap[frame].pte->frame | PG_ONSWAP; // Find the dirty bit unsigned int dirty = coremap[frame].pte->frame & PG_DIRTY; if (dirty) { // Increment dirty eviction evict_dirty_count++; } else { evict_clean_count++; } } // Update the page table entry p->frame = frame << PAGE_SHIFT; // Record information for virtual page that will now be stored in frame coremap[frame].in_use = 1; coremap[frame].pte = p; return frame; }
/* * Allocates a frame to be used for the virtual page represented by p. * If all frames are in use, calls the replacement algorithm's evict_fcn to * select a victim frame. Writes victim to swap if needed, and updates * pagetable entry for victim to indicate that virtual page is no longer in * (simulated) physical memory. * * Counters for evictions should be updated appropriately in this function. * * @param: second-level page table entry pointer * @return: frame number */ int allocate_frame(pgtbl_entry_t *p) { int fn = -1; int i; // select frame from physical memory for(i = 0; i < memsize; i++) { if(!coremap[i].in_use) { fn = i; break; } } // If all frame is in used, use schedule algorithm to select a frame if(fn == -1) { fn = evict_fcn(); pgtbl_entry_t *victim = coremap[fn].pte; off_t swap_off = victim->swap_off; victim->frame &= (~PG_VALID); // counting if((victim->frame & PG_DIRTY)) evict_dirty_count++; else evict_clean_count++; // evicted and dirty page should be written to swap file if(!(victim->frame & PG_ONSWAP) || (victim->frame & PG_DIRTY)) { victim->frame &= (~PG_DIRTY); off_t ret_off = swap_pageout((victim->frame)>>PAGE_SHIFT, swap_off); if(ret_off != -1) { victim->swap_off = ret_off; } else { perror("swap_pageout error\n"); fprintf(stderr, "not on swap error"); exit(1); } }
/* * Allocates a frame to be used for the virtual page represented by p. * If all frames are in use, calls the replacement algorithm's evict_fcn to * select a victim frame. Writes victim to swap if needed, and updates * pagetable entry for victim to indicate that virtual page is no longer in * (simulated) physical memory. * * Counters for evictions should be updated appropriately in this function. */ int allocate_frame(pgtbl_entry_t *p) { int i; int frame = -1; for(i = 0; i < memsize; i++) { if(!coremap[i].in_use) { frame = i; break; } } if(frame == -1) { // Didn't find a free page. // Call replacement algorithm's evict function to select victim frame = evict_fcn(); // All frames were in use, so victim frame must hold some page // Write victim page to swap, if needed, and update pagetable // IMPLEMENTATION NEEDED // Take pte from coremap with given frame pgtbl_entry_t *pte = coremap[frame].pte; // Swap old one with the given frame if(pte->frame & PG_DIRTY){ pte->swap_off = swap_pageout(frame, pte->swap_off); pte->frame = pte->frame & ~PG_DIRTY; pte->frame = pte->frame | PG_ONSWAP; // Increase count for evict_dirty evict_dirty_count++; }else{ // Increase count for evict_clean evict_clean_count++; } // Frame is invalid pte->frame = pte->frame & ~PG_VALID; } // Record information for virtual page that will now be stored in frame coremap[frame].in_use = 1; coremap[frame].pte = p; coremap[frame].length = p->length; return frame; }