/* * Locate the physical frame number for the given vaddr using the page table. * * If the entry is invalid and not on swap, then this is the first reference * to the page and a (simulated) physical frame should be allocated and * initialized (using init_frame). * * If the entry is invalid and on swap, then a (simulated) physical frame * should be allocated and filled by reading the page data from swap. * * Counters for hit, miss and reference events should be incremented in * this function. */ char *find_physpage(addr_t vaddr, char type) { pgtbl_entry_t *p=NULL; // pointer to the full page table entry for vaddr unsigned idx = PGDIR_INDEX(vaddr); // get index into page directory // IMPLEMENTATION NEEDED // Use top-level page directory to get pointer to 2nd-level page table if (!(pgdir[idx].pde & PG_VALID)){ pgdir[idx] = init_second_level(); } // Use vaddr to get index into 2nd-level page table and initialize 'p' uintptr_t ptr_table = PAGE_MASK & pgdir[idx].pde; p = (pgtbl_entry_t*)(ptr_table) + PGTBL_INDEX(vaddr); // Check if p is valid or not, on swap or not, and handle appropriately // Page is present in the memory if (p->frame & PG_VALID){ hit_count++; // Page is not present in the memory } else { miss_count++; ref_count++; int frame = allocate_frame(p); // Page on disk. if (p->frame & PG_ONSWAP){ swap_pagein(frame, p->swap_off); p->frame = frame << PAGE_SHIFT; p->frame = p->frame | PG_VALID; // Page not on disk, first time access the page } else { init_frame(frame, vaddr); p->frame = frame << PAGE_SHIFT; p->frame = p->frame | PG_DIRTY; } } // Make sure that p is marked valid. Also mark it dirty // if the access type indicates that the page will be written to p->frame = p->frame | PG_VALID; if(type == 'S' || type == 'M'){ p->frame = p->frame | PG_DIRTY; } // Call replacement algorithm's ref_fcn for this page ref_fcn(p); // p is marked referenced. p->frame = p->frame | PG_REF; // Return pointer into (simulated) physical memory at start of frame return &physmem[(p->frame >> PAGE_SHIFT)*SIMPAGESIZE]; }
/* * Locate the physical frame number for the given vaddr using the page table. * * If the entry is invalid and not on swap, then this is the first reference * to the page and a (simulated) physical frame should be allocated and * initialized (using init_frame). * * If the entry is invalid and on swap, then a (simulated) physical frame * should be allocated and filled by reading the page data from swap. * * Counters for hit, miss and reference events should be incremented in * this function. */ char *find_physpage(addr_t vaddr, char type) { pgtbl_entry_t *p=NULL; // pointer to the full page table entry for vaddr unsigned idx = PGDIR_INDEX(vaddr); // get index into page directory // IMPLEMENTATION NEEDED // Use top-level page directory to get pointer to 2nd-level page table // Check if it's valid unsigned int valid_pde = pgdir[idx].pde & PG_VALID; // Not Valid, initialize a 2nd pagetable if (!valid_pde) { pgdir[idx] = init_second_level(); } // Use vaddr to get index into 2nd-level page table and initialize 'p' unsigned pgtbl_index = PGTBL_INDEX(vaddr); p = (pgtbl_entry_t *) (pgdir[idx].pde & PAGE_MASK); p = p + pgtbl_index; // Check if p is valid or not, on swap or not, and handle appropriately // Find the valid bit and the on-swap bit unsigned int valid = p->frame & PG_VALID; unsigned int on_swap = p->frame & PG_ONSWAP; // Check if it's valid if (!valid) { // Allocate a frame for p int frame = allocate_frame(p); // Update fields for OPT coremap[frame].pgtbl_idx = (int) pgtbl_index; coremap[frame].pgdir_idx = (int) idx; // On swap if (on_swap) { // Read the page from swap int success = swap_pagein(frame, p->swap_off); assert(success == 0); } // Not on swap if (!on_swap) { // Initialize the frame init_frame(frame, vaddr); // Mark it as dirty p->frame = p->frame | PG_DIRTY; } // Not Valid, so increment miss miss_count++; } // Make sure that p is marked valid and referenced. Also mark it // dirty if the access type indicates that the page will be written to. // Mark p as valid and referenced p->frame = p->frame | PG_VALID; p->frame = p->frame | PG_REF; unsigned int check = p->frame & PG_VALID; assert(check); // Check the access type if ((type == 'S') || (type == 'M')) { // Set the dirty bit p->frame = p->frame | PG_DIRTY; } // Increment ref, hit if (valid) { hit_count++; } ref_count++; // Call replacement algorithm's ref_fcn for this page ref_fcn(p); // Return pointer into (simulated) physical memory at start of frame return &physmem[(p->frame >> PAGE_SHIFT)*SIMPAGESIZE]; }