static void check_n_pages(void) { struct Page* pp, *pp0; char* addr; int i; pp = pp0 = 0; // Allocate two single pages pp = page_alloc(0); pp0 = page_alloc(0); assert(pp != 0); assert(pp0 != 0); assert(pp != pp0); //cprintf("1"); // Free pp and assign four continuous pages page_free(pp); pp = page_alloc_npages(0, 4); //cprintf("1"); assert(check_continuous(pp, 4)); // //pps = page_realloc_npages(pps, 4, 6); //assert(check_continuous(pps, 6)); //cprintf("s"); // Free four continuous pages // assert(!page_free_npages(pp, 4)); //cprintf("1"); // //assert(!page_free_npages(pps, 6)); //cprintf("s"); // Free pp and assign eight continuous pages pp = page_alloc_npages(0, 8); //cprintf("1"); assert(check_continuous(pp, 8)); //cprintf("1"); // Free four continuous pages assert(!page_free_npages(pp, 8)); //cprintf("1"); // Free pp0 and assign four continuous zero pages page_free(pp0); //cprintf("1"); pp0 = page_alloc_npages(ALLOC_ZERO, 4); //cprintf("1"); addr = (char*)page2kva(pp0); //cprintf("1"); // Check Zero for( i = 0; i < 4 * PGSIZE; i++ ){ assert(addr[i] == 0); } //cprintf("1"); // Free pages assert(!page_free_npages(pp0, 4)); cprintf("check_n_pages() succeeded!\n"); /*stone: if you want to test page_realloc_pages() function, please use this*/ //check_realloc(); }
// Return n continuous pages to chunk list. Do the following things: // 1. Check whether the n pages int the list are continue, Return -1 on Error // 2. Add the pages to the chunk list // // Return 0 if everything ok int page_free_npages(struct Page *pp, int n) { // Fill this function struct Page* t_chunck; // check if continuous physical page if (check_continuous(pp, n) == 0) return -1; // add list to chunck list, list order by physical if (chunck_list.pp_link == NULL) { chunck_list.pp_link = pp; } else { t_chunck = chunck_list.pp_link; while(1) { if (t_chunck->pp_link != NULL) t_chunck = t_chunck->pp_link; else { t_chunck->pp_link = pp; break; } } } return 0; }
static void check_n_pages(void) { struct Page* pp, *pp0; char* addr; int i; pp = pp0 = 0; // Allocate two single pages pp = page_alloc(0); pp0 = page_alloc(0); assert(pp != 0); assert(pp0 != 0); assert(pp != pp0); // Free pp and assign four continuous pages page_free(pp); pp = page_alloc_npages(0, 4); assert(check_continuous(pp, 4)); // Free four continuous pages assert(!page_free_npages(pp, 4)); // Free pp and assign eight continuous pages pp = page_alloc_npages(0, 8); assert(check_continuous(pp, 8)); // Free four continuous pages assert(!page_free_npages(pp, 8)); // Free pp0 and assign four continuous zero pages page_free(pp0); pp0 = page_alloc_npages(ALLOC_ZERO, 4); addr = (char*)page2kva(pp0); // Check Zero for( i = 0; i < 4 * PGSIZE; i++ ){ assert(addr[i] == 0); } // Free pages assert(!page_free_npages(pp0, 4)); cprintf("check_n_pages() succeeded!\n"); }
static void check_realloc_npages(void) { struct Page* pp, *pp0; char* addr; int i; pp = pp0 = 0; // Allocate two single pages pp = page_alloc(0); pp0 = page_alloc(0); assert(pp != 0); assert(pp0 != 0); assert(pp != pp0); // Free pp and pp0 page_free(pp); page_free(pp0); // Assign eight continuous pages pp = page_alloc_npages(0, 8); assert(check_continuous(pp, 8)); // Realloc to 4 pages pp0 = page_realloc_npages(pp, 8, 4); assert(pp0 == pp); assert(check_continuous(pp, 4)); // Realloc to 6 pages pp = page_realloc_npages(pp, 4, 6); assert(pp0 == pp); assert(check_continuous(pp, 6)); // Realloc to 12 pages pp0 = page_realloc_npages(pp, 6, 12); assert(check_continuous(pp0, 12)); // Free 12 continuous pages assert(!page_free_npages(pp0, 12)); cprintf("check_realloc_npages() succeeded!\n"); }
// // Allocates n continuous physical page. If (alloc_flags & ALLOC_ZERO), fills the n pages // returned physical page with '\0' bytes. Does NOT increment the reference // count of the page - the caller must do these if necessary (either explicitly // or via page_insert). // // In order to figure out the n pages when return it. // These n pages should be organized as a list. // // Returns NULL if out of free memory. // Returns NULL if n <= 0 // // Try to reuse the pages cached in the chuck list // // Hint: use page2kva and memset struct Page * page_alloc_npages(int alloc_flags, int n) { // Fill this function if(n<=0) return NULL; struct Page* allocPage=page_free_list; int found=0; while((found=check_continuous(allocPage,n))!=1) { allocPage=allocPage->pp_link; } if(found==0) return NULL; if(allocPage==page_free_list) { struct Page* after=allocPage; struct Page* tail=NULL; int i; for(i=0;i<n;i++) { if(alloc_flags & ALLOC_ZERO) { memset(page2kva(after),0,PGSIZE); } tail=after; after=after->pp_link; } page_free_list=after; tail->pp_link=NULL; } else { struct Page* prev=page_free_list; while(prev->pp_link!=allocPage) prev=prev->pp_link; struct Page* after=allocPage; struct Page* tail=NULL; int i; for(i=0;i<n;i++) { if(alloc_flags & ALLOC_ZERO) { memset(page2kva(after),0,PGSIZE); } tail=after; after=after->pp_link; } prev->pp_link=tail->pp_link; tail->pp_link=NULL; } return allocPage; }
/*stone's check-test for lab2*/ static void check_realloc(void) { struct Page* pps; pps = page_alloc_npages(0, 12); assert(check_continuous(pps, 12)); pps = page_realloc_npages(pps, 12, 16); assert(check_continuous(pps, 16)); assert(!page_free_npages(pps, 16)); pps = page_alloc_npages(0, 12); pps = page_realloc_npages(pps, 12, 4); assert(check_continuous(pps, 4)); assert(!page_free_npages(pps, 4)); pps = page_alloc_npages(0, 12); pps = page_realloc_npages(pps, 12, 12); assert(check_continuous(pps, 12)); assert(!page_free_npages(pps, 12)); cprintf("check_realloc() succeed!"); }
int main() { #if defined(HAVE_AVX512F_INSTRUCTIONS) avx512f_gather_init(); #endif for(int w = 8; w <= 8192; w = 2 * w - 1) { printf("."); fflush(stdout); for(uint64_t value = 0; value < 256; value += 1) { if(!check_constant(w,value)) return -1; } } printf("\n"); for(int w = 8; w <= 8192; w = 2 * w - 1) { printf("."); fflush(stdout); for(int runstart = 0; runstart < w * (int) sizeof(uint64_t); runstart+= w / 33 + 1) { for(int endstart = runstart; endstart < w * (int) sizeof(uint64_t); endstart += w / 11 + 1) { if(!check_continuous(w,runstart,endstart)) return -1; } } } printf("\n"); for (int w = 8; w <= 8192; w = 2 * w - 1) { printf("."); fflush(stdout); for (int step = 1; step < w * (int) sizeof(uint64_t); step += w / 33 + 1) { if (!check_step(w, step)) return -1; } } printf("\n"); for (int w = 8; w <= 8192; w = 2 * w - 1) { printf("."); fflush(stdout); for (int start = 0; start < w * (int) sizeof(uint64_t); start += w / 11 + 1) { if (!check_exponential_step(w, start)) return -1; } } printf("\n"); printf("Code looks ok.\n"); return 0; }
// Return n continuous pages to chunk list. Do the following things: // 1. Check whether the n pages int the list are continue, Return -1 on Error // 2. Add the pages to the chunk list // // Return 0 if everything ok int page_free_npages(struct Page *pp, int n) { // Fill this function /* stone's solution for lab2*/ //if (pp == NULL) return -1; if (check_continuous(pp, n) == 0) return -1; struct Page* tmp = pp; size_t i; for (i = 0; i < n-1; i++) tmp = tmp->pp_link; tmp->pp_link = chunk_list; chunk_list = pp; return 0; }
// Return n continuous pages to chunk list. Do the following things: // 1. Check whether the n pages int the list are continue, Return -1 on Error // 2. Add the pages to the chunk list // // Return 0 if everything ok int page_free_npages(struct Page *pp, int n) { // Fill this function if(check_continuous(pp,n)!=1) return -1; int i; struct Page* skip; for(i=0;i<n;i++) { skip=pp; pp=pp->pp_link; page_free(skip); } return 0; }
// Return n continuous pages to chunk list. Do the following things: // 1. Check whether the n pages int the list are continue, Return -1 on Error // 2. Add the pages to the chunk list // // Return 0 if everything ok int page_free_npages(struct Page *pp, int n) { if (check_continuous(pp,n) == 0) return -1; int i; for (i = 0; i < n; i++) { if (pp == NULL) return -1; struct Page *next = pp->pp_link; pp->pp_link = chunk_list; chunk_list = pp; pp = next; } return 0; }
struct Page * page_realloc_npages(struct Page *pp, int old_n, int new_n) { // Fill this function //stone's solution for lab2 if (new_n <= 0) return NULL; if (old_n <= 0) return NULL; if (check_continuous(pp, old_n) == 0) return NULL; if (new_n == old_n) return pp; if (new_n < old_n){ page_free_npages(pp+new_n, old_n-new_n); return pp; } //stone: when new_n > old_n ,if the tail pages is continuous, then link them directly, o.w alloc new pages. struct Page* tmp = pp + old_n; size_t i; int flag = 0; for (i = 0; i < new_n - old_n; i++){ if (tmp->pp_ref != 0){ flag = 1; break; } else tmp++; } struct Page* result; if (flag == 0){ result = pp + old_n - 1; for (i = 0; i < new_n - old_n; i++){ result->pp_link = result + 1; result++; } return pp; } else{ result = page_alloc_npages(ALLOC_ZERO, new_n); memmove(page2kva(result), page2kva(pp), old_n*PGSIZE); page_free_npages(pp, old_n); pp = result; return pp; } //return NULL; }
// // Return new_n continuous pages based on the allocated old_n pages. // You can man realloc for better understanding. // (Try to reuse the allocated pages as many as possible.) // struct Page * page_realloc_npages(struct Page *pp, int old_n, int new_n) { // Fill this function if(old_n==new_n) return pp; if(new_n<old_n) { struct Page* skip=pp; int i; for(i=0;i<new_n;i++) skip=skip->pp_link; struct Page* temp; for(i=new_n;i<old_n;i++) { temp=skip; skip=skip->pp_link; page_free(temp); } return pp; } if(new_n>old_n) { struct Page* tail=pp; int i=0; for(i=0;i<old_n-1;i++) tail=tail->pp_link; struct Page* skip=page_free_list; int found=0;int following=0; while(skip) { if(page2pa(skip)-page2pa(tail)==PGSIZE) { found=1; break; } skip=skip->pp_link; } if(found==1) { if(check_continuous(skip,new_n-old_n)==1) following=1; } if(following==1) { struct Page* prev; struct Page* after; if(skip==page_free_list) { after=skip; for(i=0;i<new_n-old_n;i++) { tail->pp_link=after; tail=after; after=after->pp_link; } tail->pp_link=NULL; page_free_list=after; } else { prev=page_free_list; while(prev->pp_link!=skip) prev=prev->pp_link; after=skip; for(i=0;i<new_n-old_n;i++) { tail->pp_link=after; tail=after; after=after->pp_link; } tail->pp_link=NULL; prev->pp_link=after; } return pp; } else { struct Page* allocPage=page_alloc_npages(1,new_n); if(allocPage==NULL) return NULL; memmove(page2kva(allocPage),page2kva(pp),old_n*PGSIZE); page_free_npages(pp,old_n); return allocPage; } } return NULL; }