📄 ml_mem.c
字号:
** counter for the current number of blocks in the memory pool
*/
int xmk_cur_blk_cnt;
/*
** counter for the maximum number of blocks in the memory pool
*/
int xmk_max_blk_cnt;
/*
** Largest memory block that was ever requested and allocated
*/
int xmk_largest_blk;
#endif
#define XMK_M_INIT_MAX \
xmk_cur_memory_fill=0; \
xmk_largest_blk=0; \
xmk_cur_blk_cnt=0; \
xmk_max_blk_cnt=0;
#define XMK_M_SET_MAX_BLKSIZE(PAR) \
if (PAR > xmk_largest_blk ) \
xmk_largest_blk = PAR;
#define XMK_M_SET_MAX_BLOCKS \
if (xmk_cur_blk_cnt > xmk_max_blk_cnt ) \
xmk_max_blk_cnt = xmk_cur_blk_cnt;
#define XMK_M_INCR_ACT \
xmk_cur_blk_cnt ++;
#define XMK_M_DECR_ACT \
if (xmk_cur_blk_cnt) xmk_cur_blk_cnt --;
#define XMK_M_ADD_CUR_MEM(PAR) \
xmk_cur_memory_fill += PAR;
#define XMK_M_SUB_CUR_MEM(PAR) \
xmk_cur_memory_fill -= PAR;
#else
#define XMK_M_INIT_MAX
#define XMK_M_SET_MAX_BLKSIZE
#define XMK_M_SET_MAX_BLOCKS
#define XMK_M_INCR_ACT
#define XMK_M_DECR_ACT
#define XMK_M_ADD_CUR_MEM
#define XMK_M_SUB_CUR_MEM
#endif /* ... XMK_ADD_PROFILE || (XMK_ADD_CQUERY_MEM && XMK_USE_DEBUGGING) */
#ifndef NO_GLOBAL_VARS
#if defined(XMK_USE_SDL_MEM)
/*
** control, if memory is initialized when allocating memory
*/
static xmk_OPT_INT xmk_MemIsInitialized = XMK_FALSE;
/*
** Root pointer = pointer to first element of linked list
*/
static xmk_T_MBLOCK * first_block ;
/*
** Pointer to last element of the linked list
*/
static xmk_T_MBLOCK * xmk_LastMemoryBlockPtr = (xmk_T_MBLOCK *) NULL ;
#endif /* ... defined(XMK_USE_SDL_MEM) */
#endif /*NO_GLOBAL_VARS*/
/*============================================================================*/
/*-MGG*/
#ifdef XMK_USE_SDL_MEM
/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
| Functionname : xmk_MemInit |
| Author : S&P Media GmbH Germany |
+------------------------------------------------------------------------------+
| |
| Description : |
| This function is to be called by the user, before dynamic memory |
| management can be used. The user has to specify the beginning and the end |
| of the area to be used for dyn.MM. |
| |
| Parameter : |
| |
| _mem_begin : |
| |
| _mem_end : |
| |
| Return : void |
| |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/
/*+FDEF E*/
#ifndef XNOPROTO
void xmk_MemInit( void * _mem_begin, void * _mem_end )
#else
void xmk_MemInit( _mem_begin, _mem_end )
void * _mem_begin;
void * _mem_end;
#endif
/*-FDEF E*/
{
xmk_T_MBLOCK * first ;
xmk_T_MBLOCK * last ;
char * _mbegin;
char * _mend;
#ifdef XMK_ADD_PRINTF_MEMORY
XMK_FUNCTION("xmk_MemInit");
#endif
XMK_BEGIN_CRITICAL_PATH;
/*
** Is memory already initialized ?
** NOTE:It is not possible to initialize memory
** again after it first initialized the first time.
** (it could be possible by setting
** xmk_MemIsInitialized to XMK_FALSE before)
*/
if ( xmk_MemIsInitialized == XMK_TRUE )
{
XMK_END_CRITICAL_PATH;
return;
}
XMK_M_INIT_MAX;
#if defined(ARM_THUMB) || defined(_GCC_)
/*
** Adjust the _mem_end - pointer so that it points to
** an address which can be divided through XMK_CPU_WORD_SIZE
** It may of course not be incremented !
*/
while (1)
{
if ( ( ( (int)_mem_end) % XMK_CPU_WORD_SIZE) != 0 )
{
_mem_end --;
}
else
break; /* DONE */
}
#endif
_mbegin = (char *) _mem_begin;
_mend = (char *) _mem_end ;
first_block = NULL ;
if( !_mem_begin )
{
#ifdef XMK_ADD_PRINTF_MEMORY
XMK_TRACE_EXIT("xmk_MemInit");
#endif
return ;
} /* END IF */
if( ( _mend - _mbegin ) < ( 2 * sizeof( xmk_T_MBLOCK ) ) )
{
#ifdef XMK_ADD_PRINTF_MEMORY
XMK_TRACE_EXIT("xmk_MemInit");
#endif
XMK_END_CRITICAL_PATH;
return ;
} /* END IF */
first = ( xmk_T_MBLOCK * )_mem_begin ;
last = ( xmk_T_MBLOCK * )_mem_end ;
/*
** For making the below work,
** it must be ensured that the "last" pointer does point
** to an address which can be divided through 4.
** It might be enough to specify the 2.nd parameter
** in the call to xmk_MemInit appropriately.
*/
last-- ;
first->used = XMK_FALSE ;
first->next = last ;
first->prev = NULL ;
last->used = XMK_TRUE ; /* was XMK_FALSE before */
last->prev = first ;
last->next = NULL ;
first_block = first ;
xmk_LastMemoryBlockPtr = last;
xmk_MemIsInitialized = XMK_TRUE;
XMK_END_CRITICAL_PATH;
#ifdef XMK_ADD_PRINTF_MEMORY
XMK_TRACE_EXIT("xmk_MemInit");
#endif
return ;
} /* END OF FUNCTION */
/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
| Functionname : xmk_Malloc |
| Author : S&P Media GmbH Germany |
+------------------------------------------------------------------------------+
| |
| Description : |
| This function tries to allocate a block of memory from the memory pool. |
| The caller specifies the size of the block and the function returns with |
| a pointer to the allocated block, upon successful completion. Otherwise, |
| if no more memory or not enough memory is available, the function returns |
| with a NULL pointer. It is up to the user how to continue when a NULL poin-|
| ter is returned. However, the ErrorHandler is called with the error number |
| ERR_N_MEM_NO_FREE. It is also an error if a block with a size of 0 is |
| requested, in which case the ErrorHandler is called with the error number |
| ERR_N_MEM_PARAM. |
| |
| The following is conditionally compiled with XMK_USE_MIN_BLKSIZE : |
| |
| The requested block size is rounded to a value of XMK_MEM_MIN_BLKSIZE, if |
| the XMK_MEM_MIN_BLKSIZE is greater than the requested block size. |
| |
| It is rounded to a value of power of 2, example for a minimum block size |
| of 64 : |
| |
| rsize = 3 -----------> Use XMK_MEM_MIN_BLKSIZE = 64 |
| rsize = 63 -----------> Use XMK_MEM_MIN_BLKSIZE = 64 |
| rsize = 65 -----------> Use 2expN = 128 |
| rsize = 127 -----------> Use 2expN = 128 |
| rsize = 129 -----------> Use 2expN = 256 |
| |
| The algorithm uses a "first fit" strategy. |
| |
| Parameter : |
| |
| size_t rsize |
| |
| Return : void * |
| |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/
/*+FDEF E*/
#ifndef XNOPROTO
void * xmk_Malloc( size_t rsize )
#else
void * xmk_Malloc( rsize )
size_t rsize;
#endif
/*-FDEF E*/
{
register xmk_T_MBLOCK * xmk_MemPtr ;
#if defined(ARM_THUMB) || defined(_GCC_)
unsigned int __TempSize;
#endif
#ifdef XMK_ADD_PRINTF_MEMORY
XMK_FUNCTION("xmk_Malloc");
#endif
XMK_BEGIN_CRITICAL_PATH;
#ifdef XMK_USE_MAX_ERR_CHECK
if (! xmk_MemIsInitialized)
{
ErrorHandler (ERR_N_INIT_SDL_MEM);
XMK_END_CRITICAL_PATH;
return ((void *) NULL);
}
/*
** At least 1 Byte requested ?
*/
if (!rsize)
{
ErrorHandler (ERR_N_MEM_PARAM);
XMK_END_CRITICAL_PATH;
return ((void*) NULL);
}
#endif
#ifdef XMK_USE_MIN_BLKSIZE
/*
** Calculate the next higher block size than the one requested.
** At least a minimum of XMK_MEM_MIN_BLKSIZE will be allocated (plus
** the overhead from the xmk_T_MBLOCK structure)
*/
rsize = xmk_EvaluateExp2Size (rsize);
#endif /* ... XMK_USE_MIN_BLKSIZE */
#if defined(ARM_THUMB) || defined(_GCC_)
/*
** Memory is allocated in blocks. Each
** block is a multiple of XMK_CPU_WORD_SIZE, e.g if XMK_CPU_WORD_SIZE is 4,
** then the block size is 4, 8, 12, 16, ...
*/
__TempSize = rsize % XMK_CPU_WORD_SIZE;
if (__TempSize)
{
rsize += (XMK_CPU_WORD_SIZE - __TempSize);
}
#endif
xmk_MemPtr = __memalloc( rsize ) ;
if( xmk_MemPtr == NULL )
{
ErrorHandler (ERR_N_MEM_NO_FREE) ;
} /* END IF */
else
{
XMK_M_INCR_ACT;
XMK_M_SET_MAX_BLOCKS;
XMK_M_SET_MAX_BLKSIZE(rsize);
xmk_MemPtr++ ;
} /* END ELSE */
#ifdef XMK_ADD_PRINTF_MEMORY
XMK_TRACE_EXIT("xmk_Malloc");
#endif
XMK_END_CRITICAL_PATH;
return( ( void* ) xmk_MemPtr ) ;
} /* END OF FUNCTION */
/* ====================================================================== */
/* = = */
/* = _memalloc = */
/* = = */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -