diff options
Diffstat (limited to 'sys/contrib/ncsw/etc/ncsw_mem.c')
-rw-r--r-- | sys/contrib/ncsw/etc/ncsw_mem.c | 763 |
1 files changed, 763 insertions, 0 deletions
diff --git a/sys/contrib/ncsw/etc/ncsw_mem.c b/sys/contrib/ncsw/etc/ncsw_mem.c new file mode 100644 index 0000000..f82f0f4 --- /dev/null +++ b/sys/contrib/ncsw/etc/ncsw_mem.c @@ -0,0 +1,763 @@ +/****************************************************************************** + + © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc. + All rights reserved. + + This is proprietary source code of Freescale Semiconductor Inc., + and its use is subject to the NetComm Device Drivers EULA. + The copyright notice above does not evidence any actual or intended + publication of such source code. + + ALTERNATIVELY, redistribution and use in source and binary forms, with + or without modification, are permitted provided that the following + conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Freescale Semiconductor nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + + **************************************************************************/ +#include "error_ext.h" +#include "part_ext.h" +#include "std_ext.h" +#include "string_ext.h" +#include "mem_ext.h" +#include "mem.h" +#include "xx_ext.h" + + +#define PAD_ALIGNMENT(align, x) (((x)%(align)) ? ((align)-((x)%(align))) : 0) + +#define ALIGN_BLOCK(p_Block, prefixSize, alignment) \ + do { \ + p_Block += (prefixSize); \ + p_Block += PAD_ALIGNMENT((alignment), (uintptr_t)(p_Block)); \ + } while (0) + +#if defined(__GNUC__) +#define GET_CALLER_ADDR \ + __asm__ ("mflr %0" : "=r" (callerAddr)) +#elif defined(__MWERKS__) +/* NOTE: This implementation is only valid for CodeWarrior for PowerPC */ +#define GET_CALLER_ADDR \ + __asm__("add %0, 0, %0" : : "r" (callerAddr)) +#endif /* defined(__GNUC__) */ + + +/*****************************************************************************/ +static __inline__ void * MemGet(t_MemorySegment *p_Mem) +{ + uint8_t *p_Block; + + /* check if there is an available block */ + if (p_Mem->current == p_Mem->num) + { + p_Mem->getFailures++; + return NULL; + } + + /* get the block */ + p_Block = p_Mem->p_BlocksStack[p_Mem->current]; +#ifdef DEBUG + p_Mem->p_BlocksStack[p_Mem->current] = NULL; +#endif /* DEBUG */ + /* advance current index */ + p_Mem->current++; + + return (void *)p_Block; +} + +/*****************************************************************************/ +static __inline__ t_Error MemPut(t_MemorySegment *p_Mem, void *p_Block) +{ + /* check if blocks stack is full */ + if (p_Mem->current > 0) + { + /* decrease current index */ + p_Mem->current--; + /* put the block */ + p_Mem->p_BlocksStack[p_Mem->current] = (uint8_t *)p_Block; + return E_OK; + } + + RETURN_ERROR(MAJOR, E_FULL, NO_MSG); +} + + +#ifdef DEBUG_MEM_LEAKS + +/*****************************************************************************/ +static t_Error InitMemDebugDatabase(t_MemorySegment *p_Mem) +{ + p_Mem->p_MemDbg = (void *)XX_Malloc(sizeof(t_MemDbg) * p_Mem->num); + if (!p_Mem->p_MemDbg) + { + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory debug object")); + } + + memset(p_Mem->p_MemDbg, ILLEGAL_BASE, sizeof(t_MemDbg) * p_Mem->num); + + return E_OK; +} + + +/*****************************************************************************/ +static t_Error DebugMemGet(t_Handle h_Mem, void *p_Block, uintptr_t ownerAddress) +{ + t_MemorySegment *p_Mem = (t_MemorySegment *)h_Mem; + t_MemDbg *p_MemDbg = (t_MemDbg *)p_Mem->p_MemDbg; + uint32_t blockIndex; + + ASSERT_COND(ownerAddress != ILLEGAL_BASE); + + /* Find block num */ + if (p_Mem->consecutiveMem) + { + blockIndex = + (((uint8_t *)p_Block - (p_Mem->p_Bases[0] + p_Mem->blockOffset)) / p_Mem->blockSize); + } + else + { + blockIndex = *(uint32_t *)((uint8_t *)p_Block - 4); + } + + ASSERT_COND(blockIndex < p_Mem->num); + ASSERT_COND(p_MemDbg[blockIndex].ownerAddress == ILLEGAL_BASE); + + p_MemDbg[blockIndex].ownerAddress = ownerAddress; + + return E_OK; +} + +/*****************************************************************************/ +static t_Error DebugMemPut(t_Handle h_Mem, void *p_Block) +{ + t_MemorySegment *p_Mem = (t_MemorySegment *)h_Mem; + t_MemDbg *p_MemDbg = (t_MemDbg *)p_Mem->p_MemDbg; + uint32_t blockIndex; + uint8_t *p_Temp; + + /* Find block num */ + if (p_Mem->consecutiveMem) + { + blockIndex = + (((uint8_t *)p_Block - (p_Mem->p_Bases[0] + p_Mem->blockOffset)) / p_Mem->blockSize); + + if (blockIndex >= p_Mem->num) + { + RETURN_ERROR(MAJOR, E_INVALID_ADDRESS, + ("Freed address (0x%08x) does not belong to this pool", p_Block)); + } + } + else + { + blockIndex = *(uint32_t *)((uint8_t *)p_Block - 4); + + if (blockIndex >= p_Mem->num) + { + RETURN_ERROR(MAJOR, E_INVALID_ADDRESS, + ("Freed address (0x%08x) does not belong to this pool", p_Block)); + } + + /* Verify that the block matches the corresponding base */ + p_Temp = p_Mem->p_Bases[blockIndex]; + + ALIGN_BLOCK(p_Temp, p_Mem->prefixSize, p_Mem->alignment); + + if (p_Temp == p_Mem->p_Bases[blockIndex]) + p_Temp += p_Mem->alignment; + + if (p_Temp != p_Block) + { + RETURN_ERROR(MAJOR, E_INVALID_ADDRESS, + ("Freed address (0x%08x) does not belong to this pool", p_Block)); + } + } + + if (p_MemDbg[blockIndex].ownerAddress == ILLEGAL_BASE) + { + RETURN_ERROR(MAJOR, E_ALREADY_FREE, + ("Attempt to free unallocated address (0x%08x)", p_Block)); + } + + p_MemDbg[blockIndex].ownerAddress = (uintptr_t)ILLEGAL_BASE; + + return E_OK; +} + +#endif /* DEBUG_MEM_LEAKS */ + + +/*****************************************************************************/ +uint32_t MEM_ComputePartitionSize(uint32_t num, + uint16_t dataSize, + uint16_t prefixSize, + uint16_t postfixSize, + uint16_t alignment) +{ + uint32_t blockSize = 0, pad1 = 0, pad2 = 0; + + /* Make sure that the alignment is at least 4 */ + if (alignment < 4) + { + alignment = 4; + } + + pad1 = (uint32_t)PAD_ALIGNMENT(4, prefixSize); + /* Block size not including 2nd padding */ + blockSize = pad1 + prefixSize + dataSize + postfixSize; + pad2 = PAD_ALIGNMENT(alignment, blockSize); + /* Block size including 2nd padding */ + blockSize += pad2; + + return ((num * blockSize) + alignment); +} + +/*****************************************************************************/ +t_Error MEM_Init(char name[], + t_Handle *p_Handle, + uint32_t num, + uint16_t dataSize, + uint16_t prefixSize, + uint16_t postfixSize, + uint16_t alignment) +{ + uint8_t *p_Memory; + uint32_t allocSize; + t_Error errCode; + + allocSize = MEM_ComputePartitionSize(num, + dataSize, + prefixSize, + postfixSize, + alignment); + + p_Memory = (uint8_t *)XX_Malloc(allocSize); + if (!p_Memory) + { + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment")); + } + + errCode = MEM_InitByAddress(name, + p_Handle, + num, + dataSize, + prefixSize, + postfixSize, + alignment, + p_Memory); + if (errCode != E_OK) + { + RETURN_ERROR(MAJOR, errCode, NO_MSG); + } + + ((t_MemorySegment *)(*p_Handle))->allocOwner = e_MEM_ALLOC_OWNER_LOCAL; + + return E_OK; +} + + +/*****************************************************************************/ +t_Error MEM_InitByAddress(char name[], + t_Handle *p_Handle, + uint32_t num, + uint16_t dataSize, + uint16_t prefixSize, + uint16_t postfixSize, + uint16_t alignment, + uint8_t *p_Memory) +{ + t_MemorySegment *p_Mem; + uint32_t i, blockSize; + uint16_t alignPad, endPad; + uint8_t *p_Blocks; + + /* prepare in case of error */ + *p_Handle = NULL; + + if (!p_Memory) + { + RETURN_ERROR(MAJOR, E_NULL_POINTER, ("Memory blocks")); + } + + p_Blocks = p_Memory; + + /* make sure that the alignment is at least 4 and power of 2 */ + if (alignment < 4) + { + alignment = 4; + } + else if (!POWER_OF_2(alignment)) + { + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Alignment (should be power of 2)")); + } + + /* first allocate the segment descriptor */ + p_Mem = (t_MemorySegment *)XX_Malloc(sizeof(t_MemorySegment)); + if (!p_Mem) + { + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment structure")); + } + + /* allocate the blocks stack */ + p_Mem->p_BlocksStack = (uint8_t **)XX_Malloc(num * sizeof(uint8_t*)); + if (!p_Mem->p_BlocksStack) + { + XX_Free(p_Mem); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment block pointers stack")); + } + + /* allocate the blocks bases array */ + p_Mem->p_Bases = (uint8_t **)XX_Malloc(sizeof(uint8_t*)); + if (!p_Mem->p_Bases) + { + MEM_Free(p_Mem); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment base pointers array")); + } + memset(p_Mem->p_Bases, 0, sizeof(uint8_t*)); + + /* store info about this segment */ + p_Mem->num = num; + p_Mem->current = 0; + p_Mem->dataSize = dataSize; + p_Mem->p_Bases[0] = p_Blocks; + p_Mem->getFailures = 0; + p_Mem->allocOwner = e_MEM_ALLOC_OWNER_EXTERNAL; + p_Mem->consecutiveMem = TRUE; + p_Mem->prefixSize = prefixSize; + p_Mem->postfixSize = postfixSize; + p_Mem->alignment = alignment; + /* store name */ + strncpy(p_Mem->name, name, MEM_MAX_NAME_LENGTH-1); + + p_Mem->h_Spinlock = XX_InitSpinlock(); + if (!p_Mem->h_Spinlock) + { + MEM_Free(p_Mem); + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't create spinlock!")); + } + + alignPad = (uint16_t)PAD_ALIGNMENT(4, prefixSize); + /* Make sure the entire size is a multiple of alignment */ + endPad = (uint16_t)PAD_ALIGNMENT(alignment, (alignPad + prefixSize + dataSize + postfixSize)); + + /* The following manipulation places the data of block[0] in an aligned address, + since block size is aligned the following block datas will all be aligned */ + ALIGN_BLOCK(p_Blocks, prefixSize, alignment); + + blockSize = (uint32_t)(alignPad + prefixSize + dataSize + postfixSize + endPad); + + /* initialize the blocks */ + for (i=0; i < num; i++) + { + p_Mem->p_BlocksStack[i] = p_Blocks; + p_Blocks += blockSize; + } + + /* return handle to caller */ + *p_Handle = (t_Handle)p_Mem; + +#ifdef DEBUG_MEM_LEAKS + { + t_Error errCode = InitMemDebugDatabase(p_Mem); + + if (errCode != E_OK) + RETURN_ERROR(MAJOR, errCode, NO_MSG); + + p_Mem->blockOffset = (uint32_t)(p_Mem->p_BlocksStack[0] - p_Mem->p_Bases[0]); + p_Mem->blockSize = blockSize; + } +#endif /* DEBUG_MEM_LEAKS */ + + return E_OK; +} + + +/*****************************************************************************/ +t_Error MEM_InitSmart(char name[], + t_Handle *p_Handle, + uint32_t num, + uint16_t dataSize, + uint16_t prefixSize, + uint16_t postfixSize, + uint16_t alignment, + uint8_t memPartitionId, + bool consecutiveMem) +{ + t_MemorySegment *p_Mem; + uint32_t i, blockSize; + uint16_t alignPad, endPad; + + /* prepare in case of error */ + *p_Handle = NULL; + + /* make sure that size is always a multiple of 4 */ + if (dataSize & 3) + { + dataSize &= ~3; + dataSize += 4; + } + + /* make sure that the alignment is at least 4 and power of 2 */ + if (alignment < 4) + { + alignment = 4; + } + else if (!POWER_OF_2(alignment)) + { + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Alignment (should be power of 2)")); + } + + /* first allocate the segment descriptor */ + p_Mem = (t_MemorySegment *)XX_Malloc(sizeof(t_MemorySegment)); + if (!p_Mem) + { + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment structure")); + } + + /* allocate the blocks stack */ + p_Mem->p_BlocksStack = (uint8_t **)XX_Malloc(num * sizeof(uint8_t*)); + if (!p_Mem->p_BlocksStack) + { + MEM_Free(p_Mem); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment block pointers stack")); + } + + /* allocate the blocks bases array */ + p_Mem->p_Bases = (uint8_t **)XX_Malloc((consecutiveMem ? 1 : num) * sizeof(uint8_t*)); + if (!p_Mem->p_Bases) + { + MEM_Free(p_Mem); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment base pointers array")); + } + memset(p_Mem->p_Bases, 0, (consecutiveMem ? 1 : num) * sizeof(uint8_t*)); + + /* store info about this segment */ + p_Mem->num = num; + p_Mem->current = 0; + p_Mem->dataSize = dataSize; + p_Mem->getFailures = 0; + p_Mem->allocOwner = e_MEM_ALLOC_OWNER_LOCAL_SMART; + p_Mem->consecutiveMem = consecutiveMem; + p_Mem->prefixSize = prefixSize; + p_Mem->postfixSize = postfixSize; + p_Mem->alignment = alignment; + + p_Mem->h_Spinlock = XX_InitSpinlock(); + if (!p_Mem->h_Spinlock) + { + MEM_Free(p_Mem); + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't create spinlock!")); + } + + alignPad = (uint16_t)PAD_ALIGNMENT(4, prefixSize); + /* Make sure the entire size is a multiple of alignment */ + endPad = (uint16_t)PAD_ALIGNMENT(alignment, alignPad + prefixSize + dataSize + postfixSize); + + /* Calculate blockSize */ + blockSize = (uint32_t)(alignPad + prefixSize + dataSize + postfixSize + endPad); + + /* Now allocate the blocks */ + if (p_Mem->consecutiveMem) + { + /* |alignment - 1| bytes at most will be discarded in the beginning of the + received segment for alignment reasons, therefore the allocation is of: + (alignment + (num * block size)). */ + uint8_t *p_Blocks = (uint8_t *) + XX_MallocSmart((uint32_t)((num * blockSize) + alignment), memPartitionId, 1); + if (!p_Blocks) + { + MEM_Free(p_Mem); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment blocks")); + } + + /* Store the memory segment address */ + p_Mem->p_Bases[0] = p_Blocks; + + /* The following manipulation places the data of block[0] in an aligned address, + since block size is aligned the following block datas will all be aligned.*/ + ALIGN_BLOCK(p_Blocks, prefixSize, alignment); + + /* initialize the blocks */ + for (i = 0; i < num; i++) + { + p_Mem->p_BlocksStack[i] = p_Blocks; + p_Blocks += blockSize; + } + +#ifdef DEBUG_MEM_LEAKS + p_Mem->blockOffset = (uint32_t)(p_Mem->p_BlocksStack[0] - p_Mem->p_Bases[0]); + p_Mem->blockSize = blockSize; +#endif /* DEBUG_MEM_LEAKS */ + } + else + { + /* |alignment - 1| bytes at most will be discarded in the beginning of the + received segment for alignment reasons, therefore the allocation is of: + (alignment + block size). */ + for (i = 0; i < num; i++) + { + uint8_t *p_Block = (uint8_t *) + XX_MallocSmart((uint32_t)(blockSize + alignment), memPartitionId, 1); + if (!p_Block) + { + MEM_Free(p_Mem); + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment blocks")); + } + + /* Store the memory segment address */ + p_Mem->p_Bases[i] = p_Block; + + /* The following places the data of each block in an aligned address */ + ALIGN_BLOCK(p_Block, prefixSize, alignment); + +#ifdef DEBUG_MEM_LEAKS + /* Need 4 bytes before the meaningful bytes to store the block index. + We know we have them because alignment is at least 4 bytes. */ + if (p_Block == p_Mem->p_Bases[i]) + p_Block += alignment; + + *(uint32_t *)(p_Block - 4) = i; +#endif /* DEBUG_MEM_LEAKS */ + + p_Mem->p_BlocksStack[i] = p_Block; + } + } + + /* store name */ + strncpy(p_Mem->name, name, MEM_MAX_NAME_LENGTH-1); + + /* return handle to caller */ + *p_Handle = (t_Handle)p_Mem; + +#ifdef DEBUG_MEM_LEAKS + { + t_Error errCode = InitMemDebugDatabase(p_Mem); + + if (errCode != E_OK) + RETURN_ERROR(MAJOR, errCode, NO_MSG); + } +#endif /* DEBUG_MEM_LEAKS */ + + return E_OK; +} + + +/*****************************************************************************/ +void MEM_Free(t_Handle h_Mem) +{ + t_MemorySegment *p_Mem = (t_MemorySegment*)h_Mem; + uint32_t num, i; + + /* Check MEM leaks */ + MEM_CheckLeaks(h_Mem); + + if (p_Mem) + { + num = p_Mem->consecutiveMem ? 1 : p_Mem->num; + + if (p_Mem->allocOwner == e_MEM_ALLOC_OWNER_LOCAL_SMART) + { + for (i=0; i < num; i++) + { + if (p_Mem->p_Bases[i]) + { + XX_FreeSmart(p_Mem->p_Bases[i]); + } + } + } + else if (p_Mem->allocOwner == e_MEM_ALLOC_OWNER_LOCAL) + { + for (i=0; i < num; i++) + { + if (p_Mem->p_Bases[i]) + { + XX_Free(p_Mem->p_Bases[i]); + } + } + } + + if (p_Mem->h_Spinlock) + XX_FreeSpinlock(p_Mem->h_Spinlock); + + if (p_Mem->p_Bases) + XX_Free(p_Mem->p_Bases); + + if (p_Mem->p_BlocksStack) + XX_Free(p_Mem->p_BlocksStack); + +#ifdef DEBUG_MEM_LEAKS + if (p_Mem->p_MemDbg) + XX_Free(p_Mem->p_MemDbg); +#endif /* DEBUG_MEM_LEAKS */ + + XX_Free(p_Mem); + } +} + + +/*****************************************************************************/ +void * MEM_Get(t_Handle h_Mem) +{ + t_MemorySegment *p_Mem = (t_MemorySegment *)h_Mem; + uint8_t *p_Block; + uint32_t intFlags; +#ifdef DEBUG_MEM_LEAKS + uintptr_t callerAddr = 0; + + GET_CALLER_ADDR; +#endif /* DEBUG_MEM_LEAKS */ + + ASSERT_COND(h_Mem); + + intFlags = XX_LockIntrSpinlock(p_Mem->h_Spinlock); + /* check if there is an available block */ + if ((p_Block = (uint8_t *)MemGet(p_Mem)) == NULL) + { + XX_UnlockIntrSpinlock(p_Mem->h_Spinlock, intFlags); + return NULL; + } + +#ifdef DEBUG_MEM_LEAKS + DebugMemGet(p_Mem, p_Block, callerAddr); +#endif /* DEBUG_MEM_LEAKS */ + XX_UnlockIntrSpinlock(p_Mem->h_Spinlock, intFlags); + + return (void *)p_Block; +} + + +/*****************************************************************************/ +uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[]) +{ + t_MemorySegment *p_Mem = (t_MemorySegment *)h_Mem; + uint32_t availableBlocks; + register uint32_t i; + uint32_t intFlags; +#ifdef DEBUG_MEM_LEAKS + uintptr_t callerAddr = 0; + + GET_CALLER_ADDR; +#endif /* DEBUG_MEM_LEAKS */ + + ASSERT_COND(h_Mem); + + intFlags = XX_LockIntrSpinlock(p_Mem->h_Spinlock); + /* check how many blocks are available */ + availableBlocks = (uint32_t)(p_Mem->num - p_Mem->current); + if (num > availableBlocks) + { + num = availableBlocks; + } + + for (i=0; i < num; i++) + { + /* get pointer to block */ + if ((array[i] = MemGet(p_Mem)) == NULL) + { + break; + } + +#ifdef DEBUG_MEM_LEAKS + DebugMemGet(p_Mem, array[i], callerAddr); +#endif /* DEBUG_MEM_LEAKS */ + } + XX_UnlockIntrSpinlock(p_Mem->h_Spinlock, intFlags); + + return (uint16_t)i; +} + + +/*****************************************************************************/ +t_Error MEM_Put(t_Handle h_Mem, void *p_Block) +{ + t_MemorySegment *p_Mem = (t_MemorySegment *)h_Mem; + t_Error rc; + uint32_t intFlags; + + ASSERT_COND(h_Mem); + + intFlags = XX_LockIntrSpinlock(p_Mem->h_Spinlock); + /* check if blocks stack is full */ + if ((rc = MemPut(p_Mem, p_Block)) != E_OK) + { + XX_UnlockIntrSpinlock(p_Mem->h_Spinlock, intFlags); + RETURN_ERROR(MAJOR, rc, NO_MSG); + } + +#ifdef DEBUG_MEM_LEAKS + DebugMemPut(p_Mem, p_Block); +#endif /* DEBUG_MEM_LEAKS */ + XX_UnlockIntrSpinlock(p_Mem->h_Spinlock, intFlags); + + return E_OK; +} + + +#ifdef DEBUG_MEM_LEAKS + +/*****************************************************************************/ +void MEM_CheckLeaks(t_Handle h_Mem) +{ + t_MemorySegment *p_Mem = (t_MemorySegment *)h_Mem; + t_MemDbg *p_MemDbg = (t_MemDbg *)p_Mem->p_MemDbg; + uint8_t *p_Block; + int i; + + ASSERT_COND(h_Mem); + + if (p_Mem->consecutiveMem) + { + for (i=0; i < p_Mem->num; i++) + { + if (p_MemDbg[i].ownerAddress != ILLEGAL_BASE) + { + /* Find the block address */ + p_Block = ((p_Mem->p_Bases[0] + p_Mem->blockOffset) + + (i * p_Mem->blockSize)); + + XX_Print("MEM leak: 0x%08x, Caller address: 0x%08x\n", + p_Block, p_MemDbg[i].ownerAddress); + } + } + } + else + { + for (i=0; i < p_Mem->num; i++) + { + if (p_MemDbg[i].ownerAddress != ILLEGAL_BASE) + { + /* Find the block address */ + p_Block = p_Mem->p_Bases[i]; + + ALIGN_BLOCK(p_Block, p_Mem->prefixSize, p_Mem->alignment); + + if (p_Block == p_Mem->p_Bases[i]) + p_Block += p_Mem->alignment; + + XX_Print("MEM leak: 0x%08x, Caller address: 0x%08x\n", + p_Block, p_MemDbg[i].ownerAddress); + } + } + } +} + +#endif /* DEBUG_MEM_LEAKS */ + + |