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

📄 mempfix.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. * *---------------------------------------------------------------------- *//* *	mempfix.c *	Fixed Size Memory Pool *//** [BEGIN Common Definitions] */#include "kernel.h"#include "task.h"#include "wait.h"#include "check.h"#include "mempfix.h"/** [END Common Definitions] */#if CFN_MAX_MPFID > 0#ifdef USE_FUNC_MPFCB_TABLENoinit(EXPORT MPFCB	knl_mpfcb_table[NUM_MPFID]);	/* Fixed size memory pool control block */Noinit(EXPORT QUEUE	knl_free_mpfcb);	/* FreeQue */#endif /* USE_FUNC_MPFCB_TABLE */#ifdef USE_FUNC_FIX_MEMORYPOOL_INITIALIZE/* * Initialization of fixed size memory pool control block */EXPORT ER knl_fix_memorypool_initialize( void ){	MPFCB	*mpfcb, *end;	/* Get system information */	if ( NUM_MPFID < 1 ) {		return E_SYS;	}	/* Register all control blocks onto FreeQue */	QueInit(&knl_free_mpfcb);	end = knl_mpfcb_table + NUM_MPFID;	for ( mpfcb = knl_mpfcb_table; mpfcb < end; mpfcb++ ) {		mpfcb->mpfid = 0;		knl_InitOBJLOCK(&mpfcb->lock);		QueInsert(&mpfcb->wait_queue, &knl_free_mpfcb);	}	return E_OK;}#endif /* USE_FUNC_FIX_MEMORYPOOL_INITIALIZE */#ifdef USE_FUNC_TK_CRE_MPF/* * Create fixed size memory pool */SYSCALL ID tk_cre_mpf_impl( T_CMPF *pk_cmpf ){	const ATR VALID_MPFATR = {		 TA_TPRI		|TA_RNG3		|TA_USERBUF#if USE_OBJECT_NAME		|TA_DSNAME#endif	};	MPFCB	*mpfcb;	ID	mpfid;	W	blfsz, mpfsz;	VP	mempool;	CHECK_RSATR(pk_cmpf->mpfatr, VALID_MPFATR);	CHECK_PAR(pk_cmpf->mpfcnt > 0);	CHECK_PAR(pk_cmpf->blfsz > 0);#if !USE_IMALLOC	/* TA_USERBUF must be specified if configured in no Imalloc */	CHECK_PAR((pk_cmpf->mpfatr & TA_USERBUF) != 0);#endif	CHECK_DISPATCH();	blfsz = (W)MINSZ(pk_cmpf->blfsz);	mpfsz = blfsz * pk_cmpf->mpfcnt;#if USE_IMALLOC	if ( (pk_cmpf->mpfatr & TA_USERBUF) != 0 ) {		/* Size of user buffer must be multiples of sizeof(FREEL) */		if ( blfsz != pk_cmpf->blfsz ) {			return E_PAR;		}		/* Use user buffer */		mempool = pk_cmpf->bufptr;	} else {		/* Allocate memory for memory pool */		mempool = knl_Imalloc((UW)mpfsz);		if ( mempool == NULL ) {			return E_NOMEM;		}	}#else	/* Size of user buffer must be larger than sizeof(FREEL) */	if ( blfsz != pk_cmpf->blfsz ) {		return E_PAR;	}	/* Use user buffer */	mempool = pk_cmpf->bufptr;#endif	/* Get control block from FreeQue */	DISABLE_INTERRUPT;	mpfcb = (MPFCB*)QueRemoveNext(&knl_free_mpfcb);	ENABLE_INTERRUPT;	if ( mpfcb == NULL ) {#if USE_IMALLOC		if ( (pk_cmpf->mpfatr & TA_USERBUF) == 0 ) {			knl_Ifree(mempool);		}#endif		return E_LIMIT;	}	knl_LockOBJ(&mpfcb->lock);	mpfid = ID_MPF(mpfcb - knl_mpfcb_table);	/* Initialize control block */	QueInit(&mpfcb->wait_queue);	mpfcb->exinf    = pk_cmpf->exinf;	mpfcb->mpfatr   = pk_cmpf->mpfatr;	mpfcb->mpfcnt   = mpfcb->frbcnt = pk_cmpf->mpfcnt;	mpfcb->blfsz    = blfsz;	mpfcb->mpfsz    = mpfsz;	mpfcb->unused   = mpfcb->mempool = mempool;	mpfcb->freelist = NULL;#if USE_OBJECT_NAME	if ( (pk_cmpf->mpfatr & TA_DSNAME) != 0 ) {		strncpy((char*)mpfcb->name, (char*)pk_cmpf->dsname, OBJECT_NAME_LENGTH);	}#endif	mpfcb->mpfid    = mpfid;  /* Set ID after completion */	knl_UnlockOBJ(&mpfcb->lock);	return mpfid;}#endif /* USE_FUNC_TK_CRE_MPF */#ifdef USE_FUNC_TK_DEL_MPF/* * Delete fixed size memory pool  */SYSCALL ER tk_del_mpf_impl( ID mpfid ){	MPFCB	*mpfcb;	VP	mempool = NULL;	ATR	memattr = 0;	ER	ercd = E_OK;	CHECK_MPFID(mpfid);	CHECK_DISPATCH();	mpfcb = get_mpfcb(mpfid);	knl_LockOBJ(&mpfcb->lock);	if ( mpfcb->mpfid == 0 ) {		ercd = E_NOEXS;	} else {		DISABLE_INTERRUPT;		mempool = mpfcb->mempool;		memattr = mpfcb->mpfatr;		/* Release wait state of task (E_DLT) */		knl_wait_delete(&mpfcb->wait_queue);		/* Return to FreeQue */		QueInsert(&mpfcb->wait_queue, &knl_free_mpfcb);		mpfcb->mpfid = 0;		ENABLE_INTERRUPT;	}	knl_UnlockOBJ(&mpfcb->lock);#if USE_IMALLOC	if ( (mempool != NULL) && ((memattr & TA_USERBUF) == 0) ) {		knl_Ifree(mempool);	}#endif	return ercd;}#endif /* USE_FUNC_TK_DEL_MPF */#ifdef USE_FUNC_TK_GET_MPF/* * Processing if the priority of wait task changes */LOCAL void knl_mpf_chg_pri( TCB *tcb, INT oldpri ){	MPFCB	*mpfcb;	mpfcb = get_mpfcb(tcb->wid);	knl_gcb_change_priority((GCB*)mpfcb, tcb);}/* * Definition of fixed size memory pool wait specification */LOCAL WSPEC knl_wspec_mpf_tfifo = { TTW_MPF, NULL, NULL };LOCAL WSPEC knl_wspec_mpf_tpri  = { TTW_MPF, knl_mpf_chg_pri, NULL };/* * Get fixed size memory block  */SYSCALL ER tk_get_mpf_impl( ID mpfid, VP *p_blf, TMO tmout ){	MPFCB	*mpfcb;	FREEL	*free;	ER	ercd = E_OK;	CHECK_MPFID(mpfid);	CHECK_TMOUT(tmout);	CHECK_DISPATCH();	mpfcb = get_mpfcb(mpfid);	knl_LockOBJ(&mpfcb->lock);	if ( mpfcb->mpfid == 0 ) {		ercd = E_NOEXS;		goto error_exit;	}	/* If there is no space, ready for wait */	if ( mpfcb->frbcnt <= 0 ) {		goto wait_mpf;	} else {		/* Get memory block */		if ( mpfcb->freelist != NULL ) {			free = mpfcb->freelist;			mpfcb->freelist = free->next;			*p_blf = free;		} else {			*p_blf = mpfcb->unused;			mpfcb->unused = (VB*)mpfcb->unused + mpfcb->blfsz;		}		mpfcb->frbcnt--;	}    error_exit:	knl_UnlockOBJ(&mpfcb->lock);	return ercd;wait_mpf:	/* Ready for wait */	BEGIN_CRITICAL_SECTION;	knl_ctxtsk->wspec = ( (mpfcb->mpfatr & TA_TPRI) != 0 )?				&knl_wspec_mpf_tpri: &knl_wspec_mpf_tfifo;	knl_ctxtsk->wercd = &ercd;	knl_ctxtsk->winfo.mpf.p_blf = p_blf;	knl_gcb_make_wait((GCB*)mpfcb, tmout);	knl_UnlockOBJ(&mpfcb->lock);	END_CRITICAL_SECTION;	return ercd;}#endif /* USE_FUNC_TK_GET_MPF */#ifdef USE_FUNC_TK_REL_MPF/* * Return fixed size memory block  */SYSCALL ER tk_rel_mpf_impl( ID mpfid, VP blf ){	MPFCB	*mpfcb;	TCB	*tcb;	FREEL	*free;	ER	ercd = E_OK;	CHECK_MPFID(mpfid);	CHECK_DISPATCH();	mpfcb = get_mpfcb(mpfid);	knl_LockOBJ(&mpfcb->lock);	if ( mpfcb->mpfid == 0 ) {		ercd = E_NOEXS;		goto error_exit;	}#if CHK_PAR	if ( blf < mpfcb->mempool || blf >= knl_mempool_end(mpfcb) || (((VB*)blf - (VB*)mpfcb->mempool) % mpfcb->blfsz) != 0 ) {		ercd = E_PAR;		goto error_exit;	}#endif	DISABLE_INTERRUPT;	if ( !isQueEmpty(&mpfcb->wait_queue) ) {		/* Send memory block to waiting task,		   and then release the task */		tcb = (TCB*)mpfcb->wait_queue.next;		*tcb->winfo.mpf.p_blf = blf;		knl_wait_release_ok(tcb);		ENABLE_INTERRUPT;	} else {		ENABLE_INTERRUPT;		/* Free memory block */		free = (FREEL*)blf;		free->next = mpfcb->freelist;		mpfcb->freelist = free;		mpfcb->frbcnt++;	}error_exit:	knl_UnlockOBJ(&mpfcb->lock);	return ercd;}#endif /* USE_FUNC_TK_REL_MPF */#ifdef USE_FUNC_TK_REF_MPF/* * Check fixed size pool state */SYSCALL ER tk_ref_mpf_impl( ID mpfid, T_RMPF *pk_rmpf ){	MPFCB	*mpfcb;	ER	ercd = E_OK;	CHECK_MPFID(mpfid);	CHECK_DISPATCH();	mpfcb = get_mpfcb(mpfid);	knl_LockOBJ(&mpfcb->lock);	if ( mpfcb->mpfid == 0 ) {		ercd = E_NOEXS;	} else {		DISABLE_INTERRUPT;		pk_rmpf->wtsk = knl_wait_tskid(&mpfcb->wait_queue);		ENABLE_INTERRUPT;		pk_rmpf->exinf = mpfcb->exinf;		pk_rmpf->frbcnt = mpfcb->frbcnt;	}	knl_UnlockOBJ(&mpfcb->lock);	return ercd;}#endif /* USE_FUNC_TK_REF_MPF *//* ------------------------------------------------------------------------ *//* *	Debugger support function */#if USE_DBGSPT#ifdef USE_FUNC_FIX_MEMORYPOOL_GETNAME#if USE_OBJECT_NAME/* * Get object name from control block */EXPORT ER knl_fix_memorypool_getname(ID id, UB **name){	MPFCB	*mpfcb;	ER	ercd = E_OK;	CHECK_MPFID(id);	BEGIN_DISABLE_INTERRUPT;	mpfcb = get_mpfcb(id);	if ( mpfcb->mpfid == 0 ) {		ercd = E_NOEXS;		goto error_exit;	}	if ( (mpfcb->mpfatr & TA_DSNAME) == 0 ) {		ercd = E_OBJ;		goto error_exit;	}	*name = mpfcb->name;    error_exit:	END_DISABLE_INTERRUPT;	return ercd;}#endif /* USE_OBJECT_NAME */#endif /* USE_FUNC_FIX_MEMORYPOOL_GETNAME */#ifdef USE_FUNC_TD_LST_MPF/* * Refer fixed size memory pool usage state */SYSCALL INT td_lst_mpf_impl( ID list[], INT nent ){	MPFCB	*mpfcb, *end;	INT	n = 0;	BEGIN_DISABLE_INTERRUPT;	end = knl_mpfcb_table + NUM_MPFID;	for ( mpfcb = knl_mpfcb_table; mpfcb < end; mpfcb++ ) {		if ( mpfcb->mpfid == 0 ) {			continue;		}		if ( n++ < nent ) {			*list++ = ID_MPF(mpfcb - knl_mpfcb_table);		}	}	END_DISABLE_INTERRUPT;	return n;}#endif /* USE_FUNC_TD_LST_MPF */#ifdef USE_FUNC_TD_REF_MPF/* * Refer fixed size memory pool state  */SYSCALL ER td_ref_mpf_impl( ID mpfid, TD_RMPF *pk_rmpf ){	MPFCB	*mpfcb;	ER	ercd = E_OK;	CHECK_MPFID(mpfid);	mpfcb = get_mpfcb(mpfid);	BEGIN_DISABLE_INTERRUPT;	if ( mpfcb->mpfid == 0 ) {		ercd = E_NOEXS;	} else if ( knl_isLockedOBJ(&mpfcb->lock) ) {		ercd = E_CTX;	} else {		pk_rmpf->wtsk = knl_wait_tskid(&mpfcb->wait_queue);		pk_rmpf->exinf = mpfcb->exinf;		pk_rmpf->frbcnt = mpfcb->frbcnt;	}	END_DISABLE_INTERRUPT;	return ercd;}#endif /* USE_FUNC_TD_REF_MPF */#ifdef USE_FUNC_TD_MPF_QUE/* * Refer fixed size memory wait queue  */SYSCALL INT td_mpf_que_impl( ID mpfid, ID list[], INT nent ){	MPFCB	*mpfcb;	QUEUE	*q;	ER	ercd = E_OK;	CHECK_MPFID(mpfid);	mpfcb = get_mpfcb(mpfid);	BEGIN_DISABLE_INTERRUPT;	if ( mpfcb->mpfid == 0 ) {		ercd = E_NOEXS;	} else {		INT n = 0;		for ( q = mpfcb->wait_queue.next; q != &mpfcb->wait_queue; q = q->next ) {			if ( n++ < nent ) {				*list++ = ((TCB*)q)->tskid;			}		}		ercd = n;	}	END_DISABLE_INTERRUPT;	return ercd;}#endif /* USE_FUNC_TD_MPF_QUE */#endif /* USE_DBGSPT */#endif /* CFN_MAX_MPFID */

⌨️ 快捷键说明

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