⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memory.c

📁 uT Kernel os source code for AT91
💻 C
字号:
/* *---------------------------------------------------------------------- *    micro T-Kernel * *    Copyright (C) 2006-2007 by Ken Sakamura. All rights reserved. *    micro T-Kernel is distributed under the micro T-License. *---------------------------------------------------------------------- * *    Version:   1.00.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2007/03/26. * *---------------------------------------------------------------------- *//** [BEGIN Common Definitions] */#include "kernel.h"#include <sys/imalloc.h>#include "memory.h"/** [END Common Definitions] */#ifdef USE_FUNC_SEARCHFREEAREA/* * FreeQue search *	Search the free area whose size is equal to 'blksz', *	or larger than *      'blksz' but closest. *	If it does not exist, return '&imacb->freeque'. */EXPORT QUEUE* knl_searchFreeArea( IMACB *imacb, W blksz ){	QUEUE	*q = &imacb->freeque;	/* For area whose memory pool size is less than 1/4,	   search from smaller size.	   Otherwise, search from larger size. */	if ( blksz > imacb->memsz / 4 ) {		/* Search from larger size. */		W fsz = 0;		while ( (q = q->prev) != &imacb->freeque ) {			fsz = FreeSize(q);			if ( fsz <= blksz ) {				return ( fsz < blksz )? q->next: q;			}		}		return ( fsz >= blksz )? q->next: q;	} else {		/* Search from smaller size. */		while ( (q = q->next) != &imacb->freeque ) {			if ( FreeSize(q) >= blksz ) {				break;			}		}		return q;	}}#endif /* USE_FUNC_SEARCHFREEAREA */#ifdef USE_FUNC_APPENDFREEAREA/* * 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   +-----------------------+	    +-----------------------+ */EXPORT void knl_appendFreeArea( IMACB *imacb, QUEUE *aq ){	QUEUE	*fq;	W	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 '&imacb->freeque'.	 */	fq = knl_searchFreeArea(imacb, size);	/* Register */	clrAreaFlag(aq, AREA_USE);	if ( fq != &imacb->freeque && FreeSize(fq) == size ) {		(aq + 2)->next = (fq + 1)->next;		(fq + 1)->next = aq + 2;		(aq + 2)->prev = fq + 1;		(aq + 2)->next->prev = aq + 2;		(aq + 1)->next = NULL;	} else {		QueInsert(aq + 1, fq);		(aq + 2)->next = NULL;		(aq + 2)->prev = (QUEUE*)size;	}}#endif /* USE_FUNC_APPENDFREEAREA */#ifdef USE_FUNC_REMOVEFREEQUE/* * Delete from FreeQue */EXPORT void knl_removeFreeQue( QUEUE *fq ){	if ( fq->next == NULL ) {		(fq + 1)->prev->next = (fq + 1)->next;		if ( (fq + 1)->next != NULL ) {			(fq + 1)->next->prev = (fq + 1)->prev;		}	} else {		if ( (fq + 1)->next != NULL ) {			QueInsert((fq + 1)->next - 1, fq);			(fq + 1)->next->prev = (fq + 1)->prev;		}		QueRemove(fq);	}}#endif /* USE_FUNC_REMOVEFREEQUE */#ifdef USE_FUNC_INSERTAREAQUE/* * Register area *	Insert 'ent' just after 'que.' */EXPORT void knl_insertAreaQue( QUEUE *que, QUEUE *ent ){	ent->prev = que;	ent->next = que->next;	Assign(que->next->prev, ent);	que->next = ent;}#endif /* USE_FUNC_INSERTAREAQUE */#ifdef USE_FUNC_REMOVEAREAQUE/* * Delete area */EXPORT void knl_removeAreaQue( QUEUE *aq ){	Mask(aq->prev)->next = aq->next;	Assign(aq->next->prev, Mask(aq->prev));}#endif /* USE_FUNC_REMOVEAREAQUE *//* ------------------------------------------------------------------------ */#if USE_IMALLOC/* ------------------------------------------------------------------------ */#ifdef USE_FUNC_IMACBNoinit(EXPORT IMACB *knl_imacb);#endif /* USE_FUNC_IMACB *//* ------------------------------------------------------------------------ */#ifdef USE_FUNC_IMALLOC/* * Get memory  */EXPORT void* knl_Imalloc( size_t size ){	QUEUE	*q, *aq, *aq2;	UINT	imask;	/* If it is smaller than the minimum fragment size,	   allocate the minimum size to it. */	if ( size < MIN_FRAGMENT ) {		size = MIN_FRAGMENT;	} else {		size = ROUND(size);	}	DI(imask);  /* Exclusive control by interrupt disable */	/* Search FreeQue */	q = knl_searchFreeArea(knl_imacb, size);	if ( q == &(knl_imacb->freeque) ) {		return NULL; /* Insufficient memory */	}	/* There is free area: Split from FreeQue once */	knl_removeFreeQue(q);	aq = q - 1;	/* If there are fragments smaller than the minimum fragment size,	   allocate them also */	if ( FreeSize(q) - size >= MIN_FRAGMENT + sizeof(QUEUE) ) {		/* Divide area into 2 */		aq2 = (QUEUE*)((VB*)(aq + 1) + size);		knl_insertAreaQue(aq, aq2);		/* Register remaining area to FreeQue */		knl_appendFreeArea(knl_imacb, aq2);	}	setAreaFlag(aq, AREA_USE);	EI(imask);	return (VP)q;}#endif /* USE_FUNC_IMALLOC */#ifdef USE_FUNC_ICALLOC/* * Get memory */EXPORT void* knl_Icalloc( size_t nmemb, size_t size ){	size_t	sz = nmemb * size;	void	*mem;	mem = knl_Imalloc(sz);	if ( mem == NULL ) {		return NULL;	}	memset(mem, 0, sz);	return mem;}#endif /* USE_FUNC_ICALLOC */#ifdef USE_FUNC_IFREE/* * Free memory *	It may be called during interrupt disable. In this case, need to wait *	 until interrupt is enabled and until free. */EXPORT void  knl_Ifree( void *ptr ){	QUEUE	*aq;	UINT	imask;	DI(imask);  /* Exclusive control by interrupt disable */	aq = (QUEUE*)ptr - 1;	clrAreaFlag(aq, AREA_USE);	if ( !chkAreaFlag(aq->next, AREA_USE) ) {		/* Merge with free area in after location */		knl_removeFreeQue(aq->next + 1);		knl_removeAreaQue(aq->next);	}	if ( !chkAreaFlag(aq->prev, AREA_USE) ) {		/* Merge with free area in front location */		aq = aq->prev;		knl_removeFreeQue(aq + 1);		knl_removeAreaQue(aq->next);	}	knl_appendFreeArea(knl_imacb, aq);	EI(imask);}#endif /* USE_FUNC_IFREE *//* ------------------------------------------------------------------------ */#ifdef USE_FUNC_INIT_IMALLOC/* * IMACB Initialization  */LOCAL void initIMACB( void ){	QueInit(&(knl_imacb->areaque));	QueInit(&(knl_imacb->freeque));}/* * Imalloc initial setting  */EXPORT ER knl_init_Imalloc( void ){/* Low-level memory management information */IMPORT	VP	knl_lowmem_top, knl_lowmem_limit;	VP	memend;	QUEUE	*top, *end;	/* Acquire system configuration definition information */	memend = CFN_REALMEMEND;	if ( (UW)memend > (UW)knl_lowmem_limit ) {		memend = knl_lowmem_limit;	}	/* Align top with 8 byte unit alignment */	knl_lowmem_top = (VP)(((UW)knl_lowmem_top + 7) & ~0x00000007UL);	knl_imacb = (IMACB*)knl_lowmem_top;	knl_lowmem_top = (VP)((UW)knl_lowmem_top + sizeof(IMACB));	top = (QUEUE*)knl_lowmem_top;	knl_imacb->memsz = (W)((UW)memend - (UW)knl_lowmem_top - sizeof(QUEUE)*2);	knl_lowmem_top = memend;  /* Update memory free space */	initIMACB();	/* Register on AreaQue */	end = (QUEUE*)((VB*)top + knl_imacb->memsz) + 1;	knl_insertAreaQue(&knl_imacb->areaque, end);	knl_insertAreaQue(&knl_imacb->areaque, top);	setAreaFlag(end, AREA_USE);	setAreaFlag(&knl_imacb->areaque, AREA_USE);	knl_appendFreeArea(knl_imacb, top);	return E_OK;}#endif /* USE_FUNC_INIT_IMALLOC */#endif /* USE_IMALLOC */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -