/*
 * slob_alloc: entry point into the slob allocator.
 */
static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
{
	
	struct slob_page *sp;
	struct list_head *slob_list;
	slob_t *b = NULL;
	unsigned long flags;
	int i;
	unsigned long int count_free;
	
#ifdef BESTFIT_PAGE
	slobidx_t min,prev_min;
	struct slob_page *curr;
	int flag_if;
	int check;
#else
	struct list_head *prev;
#endif
	/*arxikopoioyme ta total_alloc kai ta total_free*/
	if(flag_mem==0){
		total_alloc = 0;
		total_free = 0;
		flag_mem = 1;
	}

	if (size < SLOB_BREAK1)
		slob_list = &free_slob_small;
	else if (size < SLOB_BREAK2)
		slob_list = &free_slob_medium;
	else
		slob_list = &free_slob_large;

	spin_lock_irqsave(&slob_lock, flags);
	/* Iterate through each partially free page, try to find room */
	
	
	counter_print++;
#ifdef BESTFIT_PAGE
	
	flag_if = 0;
	curr = NULL;
	min = 0;
	prev_min = SLOB_UNITS(size);
	
	/*diatexoume th lista mexri na broyme thn kalyterh selida*/
	list_for_each_entry(sp, slob_list, list) {
#ifdef CONFIG_NUMA
	/*
	  * If there's a node specification, search for a partial
	  * page with a matching node id in the freelist.
	  */
		if (node != -1 && page_to_nid(&sp->page) != node)
			continue;
	
#endif
		/* Enough room on this page? */
		if (sp->units < prev_min){
			continue;
		}
		if(flag_if==0){
			check = check_block(sp,size,align);
			if(check){
				min = sp->units;
				curr = sp;
				flag_if = 1;
			}
		}
		else{
			if(sp->units <= min){
				check = check_block(sp,size,align);
				if(check){
					min = sp->units;
					curr = sp;
				}
			}
		}
	}
		
	//kaloyme thn slob_page_alloc
	if(curr!=NULL){
		b = slob_page_alloc(curr, size, align);
	}
	else{
		b = NULL;
	}


#else

	list_for_each_entry(sp, slob_list, list) {
#ifdef CONFIG_NUMA
		/*
		 * If there's a node specification, search for a partial
		 * page with a matching node id in the freelist.
		 */
		if (node != -1 && page_to_nid(&sp->page) != node)
			continue;
		
#endif
		
		/* Enough room on this page? */
		if (sp->units < SLOB_UNITS(size))
			continue;

		/* Attempt to alloc */
		prev = sp->list.prev;
		b = slob_page_alloc(sp, size, align);
		if (!b)
			continue;

		/* Improve fragment distribution and reduce our average
		 * search time by starting our next search here. (see
		 * Knuth vol 1, sec 2.5, pg 449) */
		if (prev != slob_list->prev &&
				slob_list->next != prev->next)
			list_move_tail(slob_list, prev->next);
		break;
	}
#endif
	spin_unlock_irqrestore(&slob_lock, flags);

	/* Not enough space: must allocate a new page */
	if (!b) {
		b = slob_new_pages(gfp & ~__GFP_ZERO, 0, node);
		if (!b)
			return NULL;
		sp = slob_page(b);
		set_slob_page(sp);

		spin_lock_irqsave(&slob_lock, flags);
		sp->units = SLOB_UNITS(PAGE_SIZE);
		sp->free = b;
		INIT_LIST_HEAD(&sp->list);
		set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
		set_slob_page_free(sp, slob_list);
		b = slob_page_alloc(sp, size, align);
		BUG_ON(!b);
		spin_unlock_irqrestore(&slob_lock, flags);
	}
	if (unlikely((gfp & __GFP_ZERO) && b))
		memset(b, 0, size);
	
	/*diatrexoyme kai tis treis listes megethon gia na metrhsoyme ta synolika free olwn twn selidwn*/
	count_free = 0;
	for(i=0;i<3;i++){
		if (i==0){
			slob_list = &free_slob_small;
		}
		else if (i==1){
			slob_list = &free_slob_medium;
		}
		else{
			slob_list = &free_slob_large; 
		}
		list_for_each_entry(sp, slob_list, list) {
			count_free = count_free + sp->units;
		}
	}
Exemple #2
0
/*
 * slob_alloc: entry point into the slob allocator.
 */
static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
{
	struct slob_page *sp = NULL;
	struct slob_page *sp_t;
	struct list_head *slob_list;
	slob_t *b = NULL;
	unsigned long flags;

	if (size < SLOB_BREAK1)
		slob_list = &free_slob_small;
	else if (size < SLOB_BREAK2)
		slob_list = &free_slob_medium;
	else
		slob_list = &free_slob_large;

	spin_lock_irqsave(&slob_lock, flags);
	/* Iterate through each partially free page, try to find room */
	list_for_each_entry(sp_t, slob_list, list) {
#ifdef CONFIG_NUMA
		/*
		 * If there's a node specification, search for a partial
		 * page with a matching node id in the freelist.
		 */
		if (node != -1 && page_to_nid(&sp_t->page) != node)
			continue;
#endif
		/* Enough room on this page? */
		if (sp_t->units < SLOB_UNITS(size))
			/* Not enough room */
			continue;

		if (sp == NULL)
			sp = sp_t;

		if (sp_t->units < sp->units)
			/* Get the smallest slob_page that
 			 * is large enough for our needs */
			sp = sp_t;
	}

	/* Attempt to alloc */
	if(sp != NULL) {
		b = slob_page_alloc(sp, size, align);
	}
	spin_unlock_irqrestore(&slob_lock, flags);

	/* Not enough space: must allocate a new page */
	if (!b) {
		b = slob_new_pages(gfp & ~__GFP_ZERO, 0, node);
		if (!b)
			return NULL;
		sp = slob_page(b);
		set_slob_page(sp);
		
		/* We allocatted a new page, increment the count */
		slob_page_count++;


		spin_lock_irqsave(&slob_lock, flags);
		sp->units = SLOB_UNITS(PAGE_SIZE);
		sp->free = b;
		INIT_LIST_HEAD(&sp->list);
		set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
		set_slob_page_free(sp, slob_list);
		b = slob_page_alloc(sp, size, align);
		BUG_ON(!b);
		spin_unlock_irqrestore(&slob_lock, flags);
	}
	if (unlikely((gfp & __GFP_ZERO) && b))
		memset(b, 0, size);
	return b;
}
Exemple #3
0
static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
{
	struct page *sp;
	struct list_head *prev;
	struct list_head *slob_list;
	slob_t *b = NULL;
	unsigned long flags;

	if (size < SLOB_BREAK1)
		slob_list = &free_slob_small;
	else if (size < SLOB_BREAK2)
		slob_list = &free_slob_medium;
	else
		slob_list = &free_slob_large;

	spin_lock_irqsave(&slob_lock, flags);
	
	list_for_each_entry(sp, slob_list, list) {
#ifdef CONFIG_NUMA
		/*
		 * If there's a node specification, search for a partial
		 * page with a matching node id in the freelist.
		 */
		if (node != NUMA_NO_NODE && page_to_nid(sp) != node)
			continue;
#endif
		
		if (sp->units < SLOB_UNITS(size))
			continue;

		
		prev = sp->list.prev;
		b = slob_page_alloc(sp, size, align);
		if (!b)
			continue;

		if (prev != slob_list->prev &&
				slob_list->next != prev->next)
			list_move_tail(slob_list, prev->next);
		break;
	}
	spin_unlock_irqrestore(&slob_lock, flags);

	
	if (!b) {
		b = slob_new_pages(gfp & ~__GFP_ZERO, 0, node);
		if (!b)
			return NULL;
		sp = slob_page(b);
		set_slob_page(sp);

		spin_lock_irqsave(&slob_lock, flags);
		sp->units = SLOB_UNITS(PAGE_SIZE);
		sp->freelist = b;
		INIT_LIST_HEAD(&sp->list);
		set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
		set_slob_page_free(sp, slob_list);
		b = slob_page_alloc(sp, size, align);
		BUG_ON(!b);
		spin_unlock_irqrestore(&slob_lock, flags);
	}
	if (unlikely((gfp & __GFP_ZERO) && b))
		memset(b, 0, size);
	return b;
}