コード例 #1
0
ファイル: mempool.c プロジェクト: yuki74w/TRON
/*
 * Free memory block
 */
LOCAL ER rel_blk( MPLCB *mplcb, void *blk )
{
	QUEUE	*aq;

	aq = (QUEUE*)blk - 1;

#if CHK_PAR
	if ( !chkAreaFlag(aq, AREA_USE) ) {
		return E_PAR;
	}
#endif
	clrAreaFlag(aq, AREA_USE);

	if ( !chkAreaFlag(aq->next, AREA_USE) ) {
		/* Merge to the next area */
		removeFreeQue(aq->next + 1);
		removeAreaQue(aq->next);
	}
	if ( !chkAreaFlag(aq->prev, AREA_USE) ) {
		/* Merge to the previous area */
		aq = aq->prev;
		removeFreeQue(aq + 1);
		removeAreaQue(aq->next);
	}

	/* Register free area onto FreeQue */
	appendFreeArea(mplcb, aq);

	return E_OK;
}
コード例 #2
0
ファイル: mempool.c プロジェクト: yuki74w/TRON
/*
 * 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);
}
コード例 #3
0
ファイル: imalloc.c プロジェクト: kidasan/tkernel
/*
 * 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;
}
コード例 #4
0
ファイル: imalloc.c プロジェクト: kidasan/tkernel
/*
 * Free memory
 *	It may be called during interrupt disable. In this case, need to wait
 *	 until interrupt is enabled and until free.
 */
LOCAL void ifree( void *ptr, IMACB *imacb )
{
	QUEUE	*aq;
	UW	imask;

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

	aq = (QUEUE*)ptr - 1;
	clrAreaFlag(aq, AREA_USE);

	if ( !chkAreaFlag(aq->next, AREA_END|AREA_USE) ) {
		/* Merge with free area in after location */
		removeFreeQue(aq->next + 1);
		removeAreaQue(aq->next);
	}

	if ( !chkAreaFlag(aq, AREA_TOP) && !chkAreaFlag(aq->prev, AREA_USE) ) {
		/* Merge with free area in front location */
		aq = aq->prev;
		removeFreeQue(aq + 1);
		removeAreaQue(aq->next);
	}

	/* If the whole page is free, then free the page.
	 * However, do not free the page if it is called during
	 * interrupt disabled.
	 */
	if ( !isDI(imask) && chkAreaFlag(aq, AREA_TOP) && chkAreaFlag(aq->next, AREA_END) ) {
		/* Free pages */
		removeAreaQue(aq->next);
		removeAreaQue(aq);
		SpinUnlock(&MemLockObj);
		EI(imask);
		RelSysMemBlk(aq);
		DI(imask);
		SpinLock(&MemLockObj);
	} else {
		/* Register free area to FreeQue */
		appendFreeArea(aq, imacb);
	}

	SpinUnlock(&MemLockObj);
	EI(imask);
}
コード例 #5
0
ファイル: raw_malloc.c プロジェクト: aaron5117/raw-os
/*
 * Free memory
 */
static void  _mem_free( void *ptr, MACB *macb )
{
	LIST	*aq;

	if ( ptr == 0 ) {
		return;
	}

	if ( macb->testmode > 0 ) {
		if ( !chkalloc(ptr, 0, macb) ) {
			return;
		}
	}

	aq = (LIST *)ptr - 1;
	clrAreaFlag(aq, AREA_USE);

	if ( !chkAreaFlag(aq->next, AREA_END|AREA_USE) ) {
		/* Merge with just next free area */
		removeFreeQue(aq->next + 1);
		removeAreaQue(aq->next);
	}

	if ( !chkAreaFlag(aq, AREA_TOP) && !chkAreaFlag(aq->previous, AREA_USE) ) {
		/* Merge with just previous free area */
		aq = aq->previous;
		removeFreeQue(aq + 1);
		removeAreaQue(aq->next);
	}

	/* If whole page is empty, then release the page itself */
	if ( chkAreaFlag(aq, AREA_TOP) && chkAreaFlag(aq->next, AREA_END) ) {
		/* Page release */
		removeAreaQue(aq->next);
		removeAreaQue(aq);
		(*macb->relblk)(aq);
	} else {
		/* Register free area in free queue */
		appendFreeArea(aq, macb);
	}
}
コード例 #6
0
ファイル: raw_malloc.c プロジェクト: aaron5117/raw-os
/*
 * 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);
}
コード例 #7
0
ファイル: raw_malloc.c プロジェクト: aaron5117/raw-os
/*
 * Memory allocation size change
 */
static void *_mem_realloc( void *ptr, RAW_U32 size, MACB *macb )
{
	LIST 	*aq;
	RAW_U32	oldsz, sz;
	
	if ( macb->testmode > 0 ) {
		if ( !chkalloc(ptr, 0, macb) ) {
			return 0;
		}
	}

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

	size = ROUND(size);

	aq = (LIST *)ptr - 1;

	if ( ptr != 0 ) {
		/* Current allocation size */
		oldsz = (RAW_U32)AreaSize(aq);

		/* Merge if next space is free space */
		if ( !chkAreaFlag(aq->next, AREA_END|AREA_USE) ) {
			removeFreeQue(aq->next + 1);
			removeAreaQue(aq->next);
		}

		sz = (RAW_U32)AreaSize(aq);
	} else {
		sz = oldsz = 0;
	}

	if ( size <= sz ) {
		if ( size > 0 ) {
			/* Fragment current area and allocate */
			allocate(aq, size, macb);
		} else {
			/* Release area */
			_mem_free(ptr, macb);
			ptr = 0;
		}
	} else {
		/* Allocate new area */
		void *newptr = _mem_malloc(size, macb);
		if ( newptr == 0 ) {
			/* Reallocate original area at original size */
			if ( ptr != 0 ) {
				allocate(aq, oldsz, macb);
			}
			return 0;
		}

		if ( ptr != 0 ) {
			
			/* Copy contents */
			raw_memcpy(newptr, ptr, oldsz);

			/* Release old area */
			_mem_free(ptr, macb);
		}
		ptr = newptr;
	}

	return ptr;
}