?? mem.c
字號:
if (pPool -> Assert && pMemory == NULL) {
#ifdef MEM_VERBOSE
memPrintAllocatedBlocks(pMemPool);
#endif
assert(!"Out of Memory");
}
archGetSetSaturationMode(bSatMode);
if (pMemory == NULL) return (void *) NULL;
return pMemory;
}
/*******************************************************
*
* memMallocAligned
* Allocate memory aligned so that it ends on a 2**k boundary.
*
* If the size requested is 0, return NULL, per ANSI C.
*
* LABEL:
* WHILE we haven't yet allocated a block DO
* Skip blocks in use.
*
* IF we hit the tail block of the pool THEN
* IF we have already wrapped through the pool once THEN
* return NULL to indicate failure to allocate.
* ELSE
* Reset the block pointer to the first block of the pool.
* Indicate that we have wrapped around.
* Continue from LABEL.
* ENDIF
*
* Merge all contiguous free blocks from the current block to the
* first in-use block or the end of the pool.
* IF the consolidated block satisfies the request THEN
* Split the block, if it is large enough, and return the
* aligned block of the split.
* ENDIF
*
* Bump the block search pointer to the next block
* ENDWHILE
*
*******************************************************/
void * (memMallocAligned)(mem_sPool * pMemPool, size_t Size)
{
bool bSatMode;
Int32 SizeNeeded = (Int32) Size;
Int32 BlockSize;
int Wrapped;
sBlockHead * pBlock;
void * pMemory = (void *) NULL;
sPool * pPool = (sPool *) pMemPool;
UInt32 Modulo;
UInt32 ModuloMask;
Int32 pStartOfModBuffer;
Int32 pEndOfModBuffer;
Int32 SpareWords;
if(bMemInitialized == false) {
Initialize();
}
if (SizeNeeded == 0)
return (void *) NULL;
bSatMode = archGetSetSaturationMode(false);
Modulo = 1;
while (SizeNeeded > Modulo)
{
Modulo = Modulo << 1;
}
ModuloMask = Modulo - 1;
ModuloMask = ~ ModuloMask;
#ifdef ADDRESSING_8
/* Allocate in 4 8-bit units only. */
SizeNeeded = ((SizeNeeded + 3) & ~3);
#endif
SizeNeeded += sizeof(sBlockHead);
pBlock = pPool -> pCurrent;
Wrapped = false;
while (true) {
/* Skip blocks in use. */
while (true) {
BlockSize = pBlock -> Size;
if (BlockSize >= 0)
break;
/* Typecasting required to force 32 bit operation and preserve negative BlockSize */
pBlock = (sBlockHead *) (((UInt32)((char *)pBlock) - BlockSize)/2);
assert ((((UWord16)pBlock) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
}
/* Found a block that is not in use. If it's the last block of the pool,
// wrap to the beginning. If we reach the end after wrapping, then we're
// out of memory. */
if (BlockSize == 0) {
if (Wrapped) {
break;
}
pBlock = pPool -> pFirst;
Wrapped = true;
continue;
}
/* Merge free blocks that immediately follow this one in an
// attempt to make the current block big enough; ask for 2 * SizeNeeded
// in order to bracket an aligned area */
BlockSize = MergeFree(pPool, pBlock, SizeNeeded+SizeNeeded);
/* If the (now merged) free block is big enough, we split it in two
// if the remainder is big enough to make it worthwhile.
//
// If the block still isn't big enough, at least we made a bigger
// free block that will make for faster allocations later. */
if (BlockSize >= SizeNeeded) {
pStartOfModBuffer = (Int32)(((((Int32)(((char *)pBlock) + Modulo - 1)) & ModuloMask)) - sizeof(sBlockHead));
while (true)
{
SpareWords = pStartOfModBuffer - (Int32)((char *)pBlock);
if ((SpareWords == 0) || (SpareWords >= ((Int32)sizeof(sBlockHead))))
{
break;
}
pStartOfModBuffer = (Int32) (pStartOfModBuffer + Modulo);
}
pEndOfModBuffer = pStartOfModBuffer + SizeNeeded - 1;
if (pEndOfModBuffer < ((Int32)((char *)pBlock)) + BlockSize)
{
pMemory = SplitBlockRev(pPool,
pBlock,
(UInt32) SpareWords);
pMemory = SplitBlock (pPool,
pMemory,
SizeNeeded);
break;
}
}
/* Move to the next candidate block and loop back up to try again */
pBlock = (sBlockHead *) ((char *) pBlock + BlockSize);
assert ((((UWord16)pBlock) & 0x0001) == 0); /* Ensure that pBlock is double-word aligned */
}
if (pPool -> Assert && pMemory == NULL) {
#ifdef MEM_VERBOSE
memPrintAllocatedBlocks(pMemPool);
#endif
assert(!"Out of Memory");
}
archGetSetSaturationMode (bSatMode);
if (pMemory == NULL)
return (void *) NULL;
return pMemory;
}
/*******************************************************
*
* Method: memRealloc
*
* Description: This function dynamically reallocates an array
*
*******************************************************/
extern void * memRealloc(mem_sPool * pMemPool,void * pData,
size_t SizeRequested)
{
bool bSatMode;
Int32 OriginalSize;
Int32 SizeNeeded;
Int32 Size = (Int32) SizeRequested;
sBlockHead * pBlock = (sBlockHead *) pData;
void * pMem;
sPool * pPool = (sPool *) pMemPool;
if(bMemInitialized == false)
{
Initialize();
}
if (Size == 0) {
memFree(pMemPool, pData);
return (void *) NULL;
}
if (pData == NULL) {
return (memMalloc)(pMemPool, (size_t) Size);
}
bSatMode = archGetSetSaturationMode(false);
/* Back up to the block's header. */
pBlock -= 1;
#ifdef ADDRESSING_8
/* Allocate in 4 complete 8-bit units only. */
SizeNeeded = ((Size + 3) & ~3);
#else
SizeNeeded = Size;
#endif
SizeNeeded += sizeof(sBlockHead);
pBlock -> Size = -(pBlock -> Size);
OriginalSize = (Int32)(pBlock -> Size - sizeof(sBlockHead));
/* Merge free memory blocks immediately following the one pointed to
// by pBlock to see if we can avoid having to copy the data. */
if (MergeFree(pPool, pBlock, SizeNeeded) >= SizeNeeded) {
pMem = SplitBlock(pPool, pBlock, SizeNeeded);
}
else {
pMem = (void *) NULL;
pBlock -> Size = -(pBlock -> Size);
}
archGetSetSaturationMode (bSatMode);
/* If the allocation was successful, we're done. */
if (pMem != NULL) {
return pMem;
}
/* We were not able to extend the block in place. Now we have to
// allocate a brand new block. */
if ((pMem = (memMalloc)(pMemPool, (size_t) Size)) == NULL) {
return (void *) NULL;
}
/* Copy the data from the old memory area to the new. If the new
// block is larger than the old block, copy all the original data.
// If the new size is smaller (the user is trimming the data), only
// copy as much old data as will fit into the new area. */
memcpy(pMem, pData, (size_t) (Size < OriginalSize ? Size : OriginalSize));
/* Once the original data is copied to the new memory, free the
// original memory. */
memFree(pMemPool, pData);
return pMem;
}
/*******************************************************
*
* Method: memCalloc
*
* Description: This function dynamically allocates an array
* with elements initialized to zero.
*
* Arguments:
* pPool - memory pool
* Elements - number of the elements
* ElementSize - size of the element
*
* Return: None
*
*******************************************************/
extern void * memCalloc(mem_sPool * pPool, size_t Elements, size_t ElementSize)
{
size_t TotalSize = Elements * ElementSize;
void * pMemory = (memMalloc)(pPool, TotalSize);
if (pMemory == (void *) NULL)
return (void *) NULL;
memset(pMemory, 0, TotalSize);
return pMemory;
}
static sBlockHead EmptyInternalMemoryPool[2];
static sBlockHead EmptyExternalMemoryPool[2];
/*******************************************************
*
* Method: Initialize
*
* Description: This function initializes the memory manager
* driver.
*
* Arguments: None
*
* Return: None
*
*******************************************************/
static void Initialize (void)
{
UInt16 i;
const mem_sPartition * pPartitionList;
/* Initialize empty pools */
memInitializePool ( &InternalMemoryPool,
EmptyInternalMemoryPool,
sizeof (EmptyInternalMemoryPool),
false,
false
);
memInitializePool ( &ExternalMemoryPool,
EmptyExternalMemoryPool,
sizeof (EmptyExternalMemoryPool),
false,
false
);
switch (InitialState.EXbit)
{
case 0:
pPartitionList = InitialState.intPartitionList;
for (i=0; i<InitialState.numIntPartitions; i++) {
assert (memIsIM(pPartitionList -> partitionAddr));
memExtendPool (&InternalMemoryPool,
pPartitionList -> partitionAddr,
pPartitionList -> partitionSize
);
pPartitionList++;
}
pPartitionList = InitialState.extPartitionList;
for (i=0; i<InitialState.numExtPartitions; i++) {
assert (memIsEM(pPartitionList -> partitionAddr));
memExtendPool (&ExternalMemoryPool,
pPartitionList -> partitionAddr,
pPartitionList -> partitionSize
);
pPartitionList++;
}
break;
case 1:
/* Ensure that no internal partitions were specified with the external memory map */
assert (InitialState.numIntPartitions == 0);
pPartitionList = InitialState.extPartitionList;
for (i=0; i<InitialState.numExtPartitions; i++) {
assert (memIsEM(pPartitionList -> partitionAddr));
memExtendPool (&ExternalMemoryPool,
pPartitionList -> partitionAddr,
pPartitionList -> partitionSize
);
pPartitionList++;
}
break;
default:
assert (false);
break;
}
bMemInitialized = true;
}
/*******************************************************
*
* Method: memInitialize
*
* Description: This function initializes the memory manager
* data structure (InitialState).
*
* Arguments:
* pMemoryState - parametr will be copied to InitialState variable
*
* Return: None
*
*******************************************************/
EXPORT void memInitialize (mem_sState * pMemoryState)
{
/* Copy MemoryState to InitialState */
memcpy((void *)&InitialState, (const void *)pMemoryState, sizeof(mem_sState));
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -