Exemple #1
0
/*
 * Get memory block
 *	'blksz' must be larger than minimum fragment size
 *	and adjusted by ROUNDSZ unit.
 */
LOCAL void* get_blk( MPLCB *mplcb, INT blksz )
{
	QUEUE	*q, *aq;

	/* Search FreeQue */
	q = searchFreeArea(mplcb, blksz);
	if ( q == &mplcb->freeque ) {
		return NULL;
	}

	/* remove free area from FreeQue */
	removeFreeQue(q);
	aq = q - 1;

	/* If there is a fragment smaller than the minimum fragment size,
	   allocate them together */
	if ( AreaSize(aq) - (UINT)blksz >= MIN_FRAGMENT + sizeof(QUEUE) ) {

		/* Divide the area into 2. */
		q = (QUEUE*)((VB*)(aq + 1) + blksz);
		insertAreaQue(aq, q);

		/* Register the remaining area onto FreeQue */
		appendFreeArea(mplcb, q);
	}
	setAreaFlag(aq, AREA_USE);

	return (void*)(aq + 1);
}
Exemple #2
0
/*
 * Get memory 
 */
LOCAL void* imalloc( size_t size, IMACB *imacb )
{
	QUEUE	*q;
	VP	mem;
	UW	imask;

	/* If it is smaller than the minimum fragment size,
	   allocate the minimum size to it. */
	if ( size < MIN_FRAGMENT ) {
		size = MIN_FRAGMENT;
	}
	size = ROUND(size);

	DI(imask);  /* Exclusive control by interrupt disable */
	SpinLock(&MemLockObj);

	/* Search FreeQue */
	q = searchFreeArea(size, imacb);
	if ( q != &imacb->freeque ) {
		/* There is free area: Split from FreeQue once */
		removeFreeQue(q);

		q = q - 1;
	} else {
		/* Reserve new pages because there is no free space */
		QUEUE	*e;
		size_t	n;

		/* Reserve pages */
		SpinUnlock(&MemLockObj);
		EI(imask);
		n = PageCount(size + sizeof(QUEUE) * 2);
		q = GetSysMemBlk(n, imacb->mematr);
		if ( q == NULL ) {
			goto err_ret;  /* Insufficient memory */
		}
		DI(imask);
		SpinLock(&MemLockObj);

		/* Register on AreaQue */
		e = (QUEUE*)((VB*)q + n * pagesz) - 1;
		insertAreaQue(&imacb->areaque, e);
		insertAreaQue(&imacb->areaque, q);
		setAreaFlag(q, AREA_TOP);
		setAreaFlag(e, AREA_END);
	}

	/* Allocate memory */
	mem = mem_alloc(q, size, imacb);

	SpinUnlock(&MemLockObj);
	EI(imask);
	return mem;

err_ret:
	BMS_DEBUG_PRINT(("imalloc error\n"));
	return NULL;
}
Exemple #3
0
/*
 * Registration in free space free queue
 *	Free queue comprises a two-tier structure: a queue linking
 *	areas of differing size in order of size, and a queue
 *	linking areas that are the same size.
 *
 *     macb->freeque
 *      |
 *	|   +-----------------------+		+-----------------------+
 *	|   | AreaQue		    |		| AreaQue		|
 *	|   +-----------------------+		+-----------------------+
 *	+----> FreeQue size order   |	 +--------> FreeQue same size ----->
 *	|   |  FreeQue same size --------+      |   EmptyQue		|
 *	|   |			    |		|			|
 *	|   |			    |		|			|
 *	|   +-----------------------+		+-----------------------+
 *	|   | AreaQue		    |		| AreaQue		|
 *	|   +-----------------------+		+-----------------------+
 */
void appendFreeArea( LIST *aq, MACB *macb )
{
	LIST	*fq;
	RAW_U32	size = (RAW_U32)AreaSize(aq);

	/* Search registration position */
	/*  Searches for a free space with the same size as 'size' or
	 *  the next largest.
	 *  If none is found, returns &freeque.
	 */
	fq = searchFreeArea(size, macb);

	/* Registration */
	clrAreaFlag(aq, AREA_USE);
	if ( fq != &macb->freeque && (RAW_U32)FreeSize(fq) == size ) {
		list_insert(fq + 1, aq + 1);
	} else {
		list_insert(fq, aq + 1);
	}
	list_init(aq + 2);
}
Exemple #4
0
/*
 * Registration of free area on FreeQue
 *	FreeQue is composed of 2 types: Queue that links the
 *	different size of areas by size and queue that links the
 *	same size of areas.
 *
 *	freeque
 *	|
 *	|   +-----------------------+	    +-----------------------+
 *	|   | AreaQue		    |	    | AreaQue		    |
 *	|   +-----------------------+	    +-----------------------+
 *	*---> FreeQue Size order    |  *----> FreeQue Same size   ----->
 *	|   | FreeQue Same size   -----*    | EmptyQue		    |
 *	|   |			    |	    |			    |
 *	|   |			    |	    |			    |
 *	|   +-----------------------+	    +-----------------------+
 *	|   | AreaQue		    |	    | AreaQue		    |
 *	v   +-----------------------+	    +-----------------------+
 */
LOCAL void appendFreeArea( MPLCB *mplcb, QUEUE *aq )
{
	QUEUE	*fq;
	INT	size = AreaSize(aq);

	/* Registration position search */
	/*  Search the free area whose size is equal to 'blksz',
	 *  or larger than 'blksz' but closest.
	 *  If it does not exist, return '&mplcb->freeque'.
	 */
	fq = searchFreeArea(mplcb, size);

	/* Register */
	clrAreaFlag(aq, AREA_USE);
	if ( fq != &mplcb->freeque && FreeSize(fq) == size ) {
		QueInsert(aq + 1, fq + 1);
	} else {
		QueInsert(aq + 1, fq);
	}
	QueInit(aq + 2);
}
Exemple #5
0
/*
 * Registration of free area on FreeQue
 *	FreeQue is composed of 2 types: Queue that links the different
 *	size of areas by size 
 *	and queue that links the same size areas.
 *
 *	imacb->freeque
 *	|
 *	|  +-----------------------+	  +-----------------------+
 *	|  | AreaQue		   |	  | AreaQue		  |
 *	|  +-----------------------+	  +-----------------------+
 *	*---> FreeQue by size	   |  *----> FreeQue same size   ---->
 *	|  | FreeQue same size    ----*   | EmptyQue		  |
 *	|  |			   |	  |			  |
 *	|  |			   |	  |			  |
 *	|  +-----------------------+	  +-----------------------+
 *	|  | AreaQue		   |	  | AreaQue		  |
 *	v  +-----------------------+	  +-----------------------+
 */
LOCAL void appendFreeArea( QUEUE *aq, IMACB *imacb )
{
	QUEUE	*fq;
	size_t	size = AreaSize(aq);

	/* Registration position search */
	/*  Search free area whose size is equal to 'blksz',
	 *  or closest and larger than 'blksz'.
	 *  If it can not be found, return '&imacb->freeque'.
	 */
	fq = searchFreeArea(size, imacb);

	/* Registration */
	clrAreaFlag(aq, AREA_USE);
	if ( (fq != &imacb->freeque) && (FreeSize(fq) == size) ) {
		QueInsert(aq + 1, fq + 1);
	} else {
		QueInsert(aq + 1, fq);
	}
	QueInit(aq + 2);
}
Exemple #6
0
/*
 * Memory allocate
 */
static void *_mem_malloc(RAW_U32 size, MACB *macb)
{
	LIST	*q;
	if ( macb->testmode) {
		chkalloc(0, 0, macb);
	}

	/* If smaller than the minimum fragment size,
	   allocate the minimum fragment size */
	if ( size > 0 && size < MIN_FRAGMENT ) {
		size = MIN_FRAGMENT;
	}

	size = ROUND(size);
	if ( size <= 0 ) {
		return 0;
	}

	/* Search free queue */
	q = searchFreeArea(size, macb);
	if ( q != &macb->freeque ) {
		/* Free space available: first, isolate from free queue */
		removeFreeQue(q);

		q = q - 1;
	} else {
		/* No free space, then allocate new page */
		q = newPage(size, macb);
		if ( q == 0 ) {
			return 0;  /* Insufficient memory */
		}
	}

	/* Allocate memory */
	return allocate(q, size, macb);
}