PVOID __KernelAllocateMemory ( ULONG ulSize, PCSTR pFileName, ULONG LineNumber ) { PAL_MEM_PREHEADER pHeader; if ( !gMemAllocMonitorInitialized ) { __KernelInitializeMemAllocMonitor(); } pHeader = RealKernelAllocateMemory(ulSize + sizeof(AL_MEM_PREHEADER) + AL_MEM_POST_PAD_SIZE); if ( pHeader ) { if ( GlobalDebugLevel >= 8 ) { KernelTrace("__KernelAllocateMemory -- %s:%lu, allocated pMem = 0x%x ...\n", pFileName, LineNumber, ACCESS_MEM_FROM_PREHEADER(pHeader)); } KernelZeroMemory(pHeader, ulSize + sizeof(AL_MEM_PREHEADER) + AL_MEM_POST_PAD_SIZE); pHeader->MemTrueSize = ulSize; KernelAcquireLock(&gMemAllocMonitorLock); gMemAllocTotalSize += ulSize; gNumberMemAllocated ++; KernelReleaseLock(&gMemAllocMonitorLock); return ACCESS_MEM_FROM_PREHEADER(pHeader); } else { KernelTrace("KernelAllocateMemory -- insufficient resources for %lu bytes -- %s:%lu!!!\n", ulSize, pFileName, LineNumber); KernelTrace("KernelAllocateMemory -- current number of allocated = %lu, size = %lu.\n", gNumberMemAllocated, gMemAllocTotalSize); /*DH DEBUG*/ memShow(0); taskShow(taskIdSelf(), 1); checkStack(0); /*force an exception*/ *(PULONG)0 = 0; return NULL; } }
VOID __KernelFreeMemory ( PVOID pMem, PCSTR pFileName, ULONG LineNumber ) { PAL_MEM_PREHEADER pHeader; if ( GlobalDebugLevel >= 8 ) { KernelTrace("__KernelAllocateMemory -- %s:%lu, to free pMem = 0x%x ...\n", pFileName, LineNumber, pMem); } pHeader = ACCESS_PREHEADER_FROM_MEM(pMem); KernelAssert(gMemAllocMonitorInitialized); KernelAcquireLock(&gMemAllocMonitorLock); gNumberMemAllocated --; gMemAllocTotalSize -= pHeader->MemTrueSize; KernelReleaseLock(&gMemAllocMonitorLock); RealKernelFreeMemory(pHeader); return; }
PVOID __KernelReAllocMemory ( PVOID pMem, ULONG ulSize, PCSTR pFileName, ULONG LineNumber ) { void* pOldMemory = (void*)pMem; void* pNewMemory = NULL; ULONG ulOldSize = KernelGetMemorySize(pOldMemory); ULONG ulNewSize = ulSize; ULONG ulCpySize = (ulOldSize >= ulNewSize) ? ulNewSize : ulOldSize; /*DH DEBUG*/ KernelTrace("__KernelReAllocMemory -- %s:%lu ...\n", pFileName, LineNumber); pNewMemory = __KernelAllocateMemory(ulNewSize, pFileName, LineNumber); if ( !pNewMemory ) { return NULL; } else { KernelCopyMemory(pNewMemory, pOldMemory, ulCpySize); } __KernelFreeMemory(pOldMemory, pFileName, LineNumber); return pNewMemory; }
VOID _KernelDumpMemoryLeak ( void ) { PLIST_ENTRY pListEntry = NULL; PAL_MEM_PREHEADER pHeader = NULL; KernelAcquireLock(&gMemAllocMonitorLock); if ( gNumberMemAllocated != 0 ) { KernelTrace ( "Memory usage: %lu memory blocks left, total size = %lu, dumped as following:\n", gNumberMemAllocated, gMemAllocTotalSize ); } if (!ALIsListEmpty(&gMemAllocMonitorList)) { pListEntry = ALGetFirstEntryList(&gMemAllocMonitorList); while (pListEntry != NULL && pListEntry != &gMemAllocMonitorList) { pHeader = ACCESS_PREHEADER_FROM_LINKAGE(pListEntry); KernelTrace ( "0x%08X, size = %06lu, %s\n", (unsigned int)ACCESS_MEM_FROM_PREHEADER(pHeader), pHeader->MemTrueSize, pHeader->Description ); pListEntry = ALGetNextEntryList(pListEntry); } } KernelReleaseLock(&gMemAllocMonitorLock); return; }
void AnscTrace2 ( ULONG ulOid, char* pDebugStr, ... ) { BOOL bModuleMatched = FALSE; ULONG ulModuleCount = sizeof(g_tModuleOidTable) / sizeof(ULONG); ULONG i = 0; if ( g_bSelectModuleOid ) { for ( i = 0; i < ulModuleCount; i++ ) { if ( (ulOid >= g_tModuleOidTable[i] ) && (ulOid < g_tModuleOidTable[i] + 0x00010000) ) { bModuleMatched = TRUE; break; } } } else { bModuleMatched = TRUE; } if ( bModuleMatched ) { char* pTempChar = (char*)AnscAllocateMemory(1024); va_list val; if ( !pTempChar ) { return; } else { va_start(val, pDebugStr); _ansc_vsprintf(pTempChar, pDebugStr, val); va_end(val); } #ifdef _ANSC_KERNEL KernelTrace(pTempChar); #else UserTrace (pTempChar); #endif AnscFreeMemory(pTempChar); } return; }
VOID __KernelInitializeMemAllocMonitor(void) { KernelTrace ( "__KernelInitializeMemAllocMonitor ...\n" ); KernelInitializeLock(&gMemAllocMonitorLock); gMemAllocTotalSize = 0; gNumberMemAllocated = 0; gMemAllocMonitorInitialized = TRUE; return; }
VOID __KernelInitializeMemAllocMonitor(void) { KernelInitializeLock(&gMemAllocMonitorLock); ALInitializeListHead(&gMemAllocMonitorList); gMemAllocTotalSize = 0; gNumberMemAllocated = 0; gMemAllocMonitorInitialized = TRUE; KernelTrace ( "__KernelInitializeMemAllocMonitor -- AL_MEM_PREHEADER size = %u ...\n", sizeof(AL_MEM_PREHEADER) ); return; }
PVOID KernelAllocateMemory ( ULONG ulSize ) { PVOID pMem; if ( ulSize == 0 ) { return NULL; } pMem = RealKernelAllocateMemory(ulSize); if ( pMem == NULL ) { KernelTrace("KernelAllocateMemory -- insufficient resources for %u bytes!!!\n", ulSize); /* * DH DEBUG * memShow(0); taskShow(taskIdSelf(), 1); checkStack(0); */ /*force an exception*/ /**(PULONG)0 = 0;*/ } else { KernelZeroMemory(pMem, ulSize); } return pMem; }
VOID __KernelFreeMemory ( PVOID pMem, PCSTR pFileName, ULONG LineNumber ) { PAL_MEM_PREHEADER pHeader; PLIST_ENTRY pListEntryTobeFreed; BOOLEAN bFound = FALSE; PLIST_ENTRY pListEntry; ULONG ulSize; KernelAssert(gMemAllocMonitorInitialized); /*DH DEBUG*/ /* KernelTrace ( "__KernelFreeMemory -- pMem = 0x%X, File: %s, Line: %lu\n", (unsigned int)pMem, pFileName, LineNumber ); */ /* * no need to validate the memory, since we don't really touch the memory * before we do the check against the list */ pHeader = ACCESS_PREHEADER_FROM_MEM(pMem); pListEntryTobeFreed = &pHeader->Linkage; /* * check if this one is still in memory pool though it may be too late */ KernelAcquireLock(&gMemAllocMonitorLock); if (!ALIsListEmpty(&gMemAllocMonitorList)) { pListEntry = ALGetFirstEntryList(&gMemAllocMonitorList); while (pListEntry != NULL && pListEntry != &gMemAllocMonitorList) { if (pListEntryTobeFreed == pListEntry) { bFound = TRUE; break; } pListEntry = ALGetNextEntryList(pListEntry); } if (!bFound) { KernelTrace ( "__KernelFreeMemory -- the memory block 0x%X is not currently in the memory pool, File: %s, Line: %lu!\n", pMem, pFileName, LineNumber ); goto ErrorExit; } } else { KernelTrace ( "__KernelFreeMemory -- the memory monitoring list is empty! File: %s, Line: %lu!\n", pFileName, LineNumber ); goto ErrorExit; } if (!ALIsListEntryValid(&pHeader->Linkage)) { KernelTrace ( "__KernelFreeMemory -- memory 0x%X is invalid, File: %s, Line: %lu!\n", pMem, pFileName, LineNumber ); goto ErrorExit; } ulSize = pHeader->MemTrueSize; /*DH DEBUG*/ /* KernelTrace ( "__KernelFreeMemory -- size = %lu\n", ulSize ); */ /* remove it from monitoring list */ ALRemoveEntryList(&pHeader->Linkage); /* reset everything in the memory block */ KernelZeroMemory(pHeader, ulSize + sizeof(AL_MEM_PREHEADER)); RealKernelFreeMemory(pHeader); gMemAllocTotalSize -= ulSize; gNumberMemAllocated --; ErrorExit: KernelReleaseLock(&gMemAllocMonitorLock); return; }
PVOID __KernelAllocateMemory ( ULONG ulSize, PCSTR pFileName, ULONG LineNumber ) { PAL_MEM_PREHEADER pHeader; PVOID pMem = NULL; if ( !gMemAllocMonitorInitialized ) { __KernelInitializeMemAllocMonitor(); } KernelAssert(ulSize != 0); /*DH DEBUG*/ /* KernelTrace ( "__KernelAllocateMemory -- size = %lu, File: %s, Line: %lu\n", ulSize, pFileName, LineNumber ); */ pHeader = (PAL_MEM_PREHEADER)RealKernelAllocateMemory(ulSize + sizeof(AL_MEM_PREHEADER)); if (pHeader) { KernelZeroMemory(pHeader, ulSize + sizeof(AL_MEM_PREHEADER)); pHeader->MemTrueSize = ulSize; pMem = ACCESS_MEM_FROM_PREHEADER(pHeader); strcpy(pHeader->Description, pFileName); strcat(pHeader->Description, ":"); sprintf(&pHeader->Description[strlen(pHeader->Description)], "%u", LineNumber); KernelAcquireLock(&gMemAllocMonitorLock); /* put it into monitoring list */ ALInsertTailList(&gMemAllocMonitorList, &pHeader->Linkage); gMemAllocTotalSize += ulSize; gNumberMemAllocated ++; KernelReleaseLock(&gMemAllocMonitorLock); /*DH DEBUG*/ /* KernelTrace ( "__KernelAllocateMemory -- allocated memory = 0x%X/0x%X\n", (unsigned int)pHeader, (unsigned int)pMem ); */ return pMem; } else { KernelTrace ( "__KernelAllocateMemory failed, size = %lu, File: %s, Line: %lu\n", ulSize, pFileName, LineNumber ); /*DH DEBUG*/ _KernelDumpMemoryLeak(); KernelAssert(FALSE); return NULL; } }
/* * eCos doesn't clean the memory blocks of stack and thread info required to create * a thread, if they are dynamically allocated. Here is how we clean them: * 1) when a thread is created, we allocate a memory block for both stack and thread info. * 2) The memory block pointer is stored into thread data, index 0 * 3) When a thread exits, it retrieves the memory block pointer from thread data, index 0 * and put it into a pool * 4) Next time when another thread exits, it first cleans up the memory block pool. * 5) In step 3) and 4), a spin lock is used to protect the memory block pool. */ KERNEL_HANDLE KernelCreateTask ( cyg_thread_entry_t* startEntry, ULONG stackSize, ULONG priority, KERNEL_HANDLE hContext, char* pName ) { ULONG ulSize = 0; PKERNEL_TASK_MEM_BLOCK pMem = NULL; PUCHAR pStack = NULL; cyg_thread* pThreadInfo = NULL; cyg_handle_t hThread = 0; ulSize = (sizeof(KERNEL_TASK_MEM_BLOCK) + CYGNUM_HAL_STACK_FRAME_SIZE) / CYGNUM_HAL_STACK_FRAME_SIZE * CYGNUM_HAL_STACK_FRAME_SIZE; pMem = (PKERNEL_TASK_MEM_BLOCK)KernelAllocateMemory(ulSize + stackSize); if ( pMem ) { pStack = pMem + ulSize; pThreadInfo = &pMem->ThreadInfo; cyg_thread_create ( priority, startEntry, hContext, pName, pStack, stackSize, &hThread, pThreadInfo ); if ( hThread ) { KernelTrace ( "KernelCreateTask -- memory block pointer for task %s is 0x%lX.\n", pName, pMem ); cyg_thread_set_data(0, pMem); cyg_thread_resume(hThread); return hThread; } } if ( pMem ) { KernelFreeMemory(pMem); } return (KERNEL_HANDLE)NULL; }
void AnscTrace3 ( char* pTraceId, char* pDebugStr, ... ) { BOOL bTraceIdMatched = FALSE; ULONG ulTraceIdCount = sizeof(g_tTraceIdTable) / sizeof(char*); ULONG i = 0; if ( g_bSelectTraceId ) { for ( i = 0; i < ulTraceIdCount; i++ ) { if ( (AnscSizeOfString(pTraceId) >= AnscSizeOfString(g_tTraceIdTable[i]))&& AnscEqualString2 ( pTraceId, g_tTraceIdTable[i], AnscSizeOfString(g_tTraceIdTable[i]), FALSE ) ) { bTraceIdMatched = TRUE; break; } } } else { bTraceIdMatched = TRUE; } if ( bTraceIdMatched ) { char* pTempChar = (char*)AnscAllocateMemory(1024); va_list val; if ( !pTempChar ) { return; } else { va_start(val, pDebugStr); _ansc_vsprintf(pTempChar, pDebugStr, val); va_end(val); } #ifdef _ANSC_KERNEL KernelTrace(pTempChar); #else UserTrace (pTempChar); #endif AnscFreeMemory(pTempChar); } return; }