void allocate_page(void) { int req_pageno = vmem->adm.req_pageno; int frame = VOID_IDX; int page_removed_idx = VOID_IDX; if(vmem->pt.entries[req_pageno].flags & PTF_PRESENT) { // no page fault! return; } /* find free page */ frame = search_bitmap(); #ifdef DEBUG_MESSAGES printf("bitmap: frame %d\n", frame); #endif // DEBUG_MESSAGES if(frame != VOID_IDX) { fprintf(stderr, "Found free frame no %d, allocation page\n", frame); update_pt(frame); fetch_page(vmem->adm.req_pageno); } else { frame = find_remove_frame(); } /* TODO: impl stuff*/ page_removed_idx = vmem->pt.framepage[frame]; /* TODO: impl stuff*/ /* Store page to be removed and clear present-bit */ if(vmem->pt.entries[page_removed_idx].flags & PTF_DIRTY) { store_page(page_removed_idx); } vmem->pt.entries[page_removed_idx].flags &= ~PTF_PRESENT; /* Load new page */ update_pt(frame); fetch_page(vmem->adm.req_pageno); /* Update page fault counter */ vmem->adm.pf_count++; // log allocation struct logevent le; le.req_pageno = vmem->adm.req_pageno; le.replaced_page = page_removed_idx; le.alloc_frame = frame; le.pf_count = vmem->adm.pf_count; le.g_count = vmem->adm.g_count; logger(le); // unblock application sem_post(&(vmem->adm.sema)); }
int mem_access(void *vaddr, int size, pte_t access) { unsigned long addr; unsigned long next; pte_t pte; addr = (unsigned long) vaddr; next = (addr & ~PAGESIZE) + PAGESIZE; while (1) { if ((GET_PDE(addr) & PT_PRESENT) == 0) return 0; pte = GET_PTE(addr); if ((pte & access) != access) { if (pte & PT_FILE) { if (fetch_page((void *) PAGEADDR(addr)) < 0) return 0; if ((GET_PTE(addr) & access) != access) return 0; } else { return 0; } } size -= next - addr; if (size <= 0) break; addr = next; next += PAGESIZE; } return 1; }
void Pager::read(void * buf, int cnt, Address address) { //cursor char * cur = static_cast<char *>(buf); //calculate aligned address Address aligned_addr = address / BLOCK_SIZE * BLOCK_SIZE; int len = std::min(BLOCK_SIZE - (address - aligned_addr), cnt); Page * tmp = fetch_page(aligned_addr); memcpy(cur, tmp->content + (address - aligned_addr), len); cnt -= len; cur += len; while(cnt){ aligned_addr += BLOCK_SIZE; len = std::min(BLOCK_SIZE, cnt); tmp = fetch_page(aligned_addr); memcpy(cur, tmp->content, len); cnt -= len; cur += len; } }
void update_pt(int frame) { int mBit; //mod bit int pagenumb = vmem->adm.req_pageno; // alte Seite aus dem Frame löschen int oldPage = vmem->pt.framepage[frame]; event.replaced_page=oldPage; if(oldPage != VOID_IDX){ vmem->pt.entries[oldPage].frame = VOID_IDX; } // die Seite in File schreiben, wenn notwendig mBit = vmem->pt.entries[oldPage].flags & PTF_DIRTY; if (oldPage != VOID_IDX && mBit == PTF_DIRTY) { store_page(oldPage); vmem->pt.entries[oldPage].flags -= PTF_DIRTY; } //neue Seite laden fetch_page(pagenumb); vmem->pt.entries[pagenumb].frame = frame; vmem->pt.entries[pagenumb].age=DEF_AGE; vmem->pt.framepage[frame] = pagenumb; }
int str_access(char *s, pte_t access) { pte_t pte; while (1) { if ((GET_PDE(s) & PT_PRESENT) == 0) return 0; pte = GET_PTE(s); if ((pte & access) != access) { if (pte & PT_FILE) { if (fetch_page((void *) PAGEADDR(s)) < 0) return 0; if ((GET_PTE(s) & access) != access) return 0; } else { return 0; } } while (1) { if (!*s) return 1; s++; if (PGOFF(s) == 0) break; } } }
void page_fault() { int page_unloaded = VOID_IDX; int new_frame = VOID_IDX; int req_page = vmem->adm.req_pageno; // Page fault aufgetreten DEBUG(fprintf(stderr, "Pagefault: Requested Page: %d\n", req_page)); vmem->adm.pf_count++; new_frame = find_remove_frame(); page_unloaded = vmem->pt.framepage[new_frame]; if( vmem_is_full() ) { store_page(page_unloaded); } update_pt(new_frame); fetch_page(req_page); // make Logs struct logevent le; le.req_pageno = vmem->adm.req_pageno; le.replaced_page = page_unloaded; le.alloc_frame = new_frame; le.pf_count = vmem->adm.pf_count; le.g_count = vmem->adm.pf_count; logger(le); DEBUG(fprintf(stderr, "Page loaded. pf_count=%d\n", vmem->adm.pf_count)); // Den aufrufenden Freigeben sem_post(&vmem->adm.sema); }