Exemple #1
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);
	//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();
}
Exemple #2
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");
}
Exemple #3
0
//
// 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)
{
	if (old_n == new_n)
		return pp;
	if (old_n > new_n)
	{
		page_free_npages(pp+new_n,old_n-new_n);
		pp[new_n-1].pp_link = NULL;
		return pp;
	}
	int i;
	bool p = 1;
	for (i = old_n; i < new_n; i++)
	{
		if (pp[i].pp_ref != 0)
		{
			p = 0;
			break;
		}
	}
	if (p == 0)
	{
		struct Page *newpp = page_alloc_npages(ALLOC_ZERO,new_n);
		memmove(page2kva(newpp),page2kva(pp),old_n*PGSIZE);
		page_free_npages(pp,old_n);
		pp = newpp;
	}else
	{
		pp[old_n-1].pp_link = pp+old_n;
		struct Page *iter = page_free_list;
		struct Page *lst = iter;
		while (iter != NULL)
		{
			if (iter >= pp+old_n && iter <= pp+new_n)
			{
				if (iter == page_free_list)
					page_free_list = iter->pp_link;
				else{
					lst->pp_link = iter->pp_link;
				}
			}else{
				lst = iter;
			}
			iter = iter->pp_link;
		}
		for (i = old_n; i < new_n; i++)
		{
			pp[i].pp_link = pp+i+1;
		}
		memset(page2kva(pp+old_n),0,(new_n-old_n)*PGSIZE);
	}
	return pp;

}
Exemple #4
0
/*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!");
}
Exemple #5
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;
}
Exemple #6
0
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");
}
Exemple #7
0
//
// 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 (new_n == 0) {
		page_free_npages(pp, old_n);
		return NULL;
	}
	
	// assume pp_ref will be added by caller 
	// need more physical pages
	if (old_n < new_n) {
		uint32_t more_n = new_n - old_n;
		uint32_t can_add_flag = 1;
		uint32_t i = 0;
	
		// if can add to tail?
		for (i = old_n; i < new_n; i++){
			// empty and not over limit 
			if ((pp+i)->pp_ref == 0 && pp+i < pages+npages ) {
				can_add_flag = 0;
				break;
			}
		}
		
		// if can't add to tail, free and alloc
		if (can_add_flag == 0){
			struct Page* new_alloc;
			new_alloc = page_alloc_npages(ALLOC_ZERO, new_n);
			memmove(page2kva(new_alloc), page2kva(pp), old_n*PGSIZE);
			page_free_npages(pp, old_n);
			return new_alloc;
		}

		// if can add
		// first, remove those from page_free_list
		struct Page* find_pp; 
		while(page_free_list > pp && page_free_list <= pp+more_n) {
			page_free_list = page_free_list->pp_link;
		}
		find_pp = page_free_list;
		while(find_pp != NULL && find_pp->pp_link != NULL) {
			if (find_pp->pp_link > pp && find_pp->pp_link <= pp+more_n) {
				find_pp->pp_link = find_pp->pp_link->pp_link;
			}
			find_pp = find_pp->pp_link;
		}

		// second, add to old alloc page list
		for (i = 0; i < more_n; i++) {
			(pp+i)->pp_link = pp+i+1;
		}
		(pp+more_n)->pp_link = NULL;

		// third, init new memory
		memset(page2kva(pp+1), 0, more_n*PGSIZE);

		// fourth, return pp
		return pp;

	} else if (old_n > new_n) {
		// free last pages
		page_free_npages(pp+new_n, old_n-new_n);
		(pp+new_n-1)->pp_link = NULL;
		return pp; 

	} else {
		// old_n == new_n, do nothing
		return pp;
	}
	return NULL;
}
Exemple #8
0
//
// 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;
}