diff -r 000000000000 -r f0f2b8682603 memana/analyzetoolclient/dynamicmemoryhook/src/analyzetoolallocator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memana/analyzetoolclient/dynamicmemoryhook/src/analyzetoolallocator.cpp Thu Feb 11 15:51:35 2010 +0200 @@ -0,0 +1,1008 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Definitions for the class RAnalyzeToolAllocator. +* +*/ + + +#include "analyzetoolallocator.h" +#include "analyzetoolmemoryallocator.h" +#include "atlog.h" +#include "analyzetoolpanics.pan" +#include "analyzetoolfastlog.h" +#include + +// CONSTANTS + +// Length of the callstack address +const TUint32 KAddressLength = 4; + +// Thread count +const TInt KThreadCount = 1; + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::RAnalyzeToolAllocator() +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +RAnalyzeToolAllocator::RAnalyzeToolAllocator( TBool aNotFirst, + RATStorageServer& aStorageServer, + RArray& aCodeblocks, + RMutex& aMutex, + TUint aProcessId, + RAnalyzeTool& aAnalyzeTool, + TBool aStorageServerOpen, + TUint32 aLogOption, + TUint32 aAllocCallStackSize, + TUint32 aFreeCallStackSize ) : + RAnalyzeToolMemoryAllocator( aNotFirst ), + iStorageServer( aStorageServer ), + iCodeblocks( aCodeblocks ), + iMutex( aMutex ), + iProcessId( aProcessId ), + iThreadArray( KATMaxCallstackLength ), + iAnalyzeTool( aAnalyzeTool ), + iStorageServerOpen( aStorageServerOpen ), + iLogOption( aLogOption ), + iAllocMaxCallStack( aAllocCallStackSize ), + iFreeMaxCallStack( aFreeCallStackSize ) + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::RAnalyzeToolAllocator()" ); + + // Append thread to array of the users of this allocator + TThreadParamsBuf params; + params().iThreadId = RThread().Id().operator TUint(); + TInt error = iAnalyzeTool.ThreadStack( params ); + if ( KErrNone == error ) + { + LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress ); + LOGSTR2( "ATMH Thread stack size: %x", params().iStackSize ); + error = iThreadArray.Append( TThreadStack( RThread().Id(), + params().iStackAddress + params().iStackSize ) ); + } + + __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) ); + } + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::~RAnalyzeToolAllocator() +// Destructor. +// ----------------------------------------------------------------------------- +// +RAnalyzeToolAllocator::~RAnalyzeToolAllocator() + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::~RAnalyzeToolAllocator()" ); + + // Close the thread array + iThreadArray.Close(); + } + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::Uninstall() +// Uninstalls the current allocator +// ----------------------------------------------------------------------------- +// +void RAnalyzeToolAllocator::Uninstall() + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::Uninstall()" ); + + // Switch back to the original allocator + SwitchOriginalAllocator(); + + // Check if this is shared allocator between threads + if ( iThreadArray.Count() > KThreadCount ) + { + // Close the shared allocator + Close(); + return; + } + +#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 ) + #ifndef __WINS__ + // Remove dummy Tls handle + UserSvr::DllFreeTls( KDummyHandle ); + #endif +#endif + + // Since this is the last thread using this allocator it can be deleted + delete this; + } + +#ifdef __WINS__ + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::Alloc() WINS version +// Allocates a cell of specified size from the heap. +// ----------------------------------------------------------------------------- +// +UEXPORT_C TAny* RAnalyzeToolAllocator::Alloc( TInt aSize ) + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc()" ); + + // Acquire the mutex + iMutex.Wait(); + + // Alloc memory from the original allocator + TAny* p = iAllocator->Alloc( aSize ); + + LOGSTR3( "ATMH RAnalyzeToolAllocator::Alloc() - aSize: %i, address: %x", + aSize, (TUint32) p ); + + // Don't collect call stack and log data + // if storage server not open or logging mode not fast xti. + if ( iStorageServerOpen || iLogOption == EATLogToXtiFast ) + { + // Reset the callstack + iCallStack.Reset(); + + // Find the current thread callstack start address + TUint32 stackstart( 0 ); + TBool found( FindCurrentThreadStack( stackstart ) ); + LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found ); + + TUint32 _sp; + __asm + { + mov [_sp], esp + } + + // Get codeblocks count + TInt blocksCount( iCodeblocks.Count() ); + TInt error( KErrNone ); + TUint arrayCounter = 0; + + for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348 + { + TUint32 addr = (TUint32) *( (TUint32*) i ); + if ( ! IsAddressLoadedCode( addr ) ) + continue; + for ( TInt j = 0; j < blocksCount; j++ ) + { + if ( iCodeblocks[j].CheckAddress( addr ) ) + { + // To avoid recursive call to ReAlloc specifying granularity + // Add address to the callstack + iCallStack[arrayCounter] = addr; + arrayCounter++; + break; + } + } + if ( arrayCounter == KATMaxCallstackLength || + arrayCounter == iAllocMaxCallStack ) + { + LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter ); + break; + } + } + // Log the memory allocation information + if ( iLogOption == EATLogToXtiFast ) + { + // Using fast xti. + ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize ); + } + else + { + // Using storage server. + error = iStorageServer.LogMemoryAllocated( (TUint32) p, + iCallStack, + aSize ); + if ( KErrNone != error ) + { + LOGSTR2( "ATMH LogMemoryAllocated error %i", error ); + switch ( error ) + { + case KErrNoMemory: + LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - KErrNoMemory case" ); + if ( iStorageServerOpen ) + { + iStorageServerOpen = EFalse; + LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - close iStorageServer" ); + iStorageServer.Close(); + } + break; + } + } + } + } + // Release the mutex + iMutex.Signal(); + + return p; + } +#else + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::Alloc() ARMV5 version +// Allocates a cell of specified size from the heap. +// ----------------------------------------------------------------------------- +// +TAny* RAnalyzeToolAllocator::Alloc( TInt aSize ) + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc()" ); + + // Acquire the mutex + iMutex.Wait(); + + // Alloc memory from the original allocator + TAny* p = iAllocator->Alloc( aSize ); + + // Don't collect call stack and log data + // if storage server not open or logging mode not fast xti. + if ( iStorageServerOpen || iLogOption == EATLogToXtiFast ) + { + // Reset the callstack + iCallStack.Reset(); + + // Find the current thread callstack start address + TUint32 stackstart( 0 ); + TBool found( FindCurrentThreadStack( stackstart ) ); + LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found ); + + // Get codeblocks count + TInt blocksCount( iCodeblocks.Count() ); + TInt error( KErrNone ); + TUint arrayCounter = 0; + + for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348 + { + for ( TInt j = 0; j < blocksCount; j++ ) + { + if ( iCodeblocks[j].CheckAddress( (TUint32) *( (TUint32*) i ) ) ) + { + // To avoid recursive call to ReAlloc specifying granularity + // Add address to the callstack + iCallStack[arrayCounter] = ( (TUint32) *( (TUint32*) i ) ); + arrayCounter++; + break; + } + } + if ( arrayCounter == KATMaxCallstackLength || + arrayCounter == iAllocMaxCallStack ) + { + LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter ); + break; + } + } + // Log the memory allocation information + if ( iLogOption == EATLogToXtiFast ) + { + // Fast xti. + ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize ); + } + else + { + // Using storage server. + error = iStorageServer.LogMemoryAllocated( (TUint32) p, + iCallStack, + aSize ); + if ( KErrNone != error ) + { + LOGSTR2( "ATMH LogMemoryAllocated error %i", error ); + switch ( error ) + { + case KErrNoMemory: + LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc() - KErrNoMemory case" ); + if ( iStorageServerOpen ) + { + iStorageServerOpen = EFalse; + LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc() - close iStorageServer" ); + iStorageServer.Close(); + } + break; + } + } + } + } + + // Release the mutex + iMutex.Signal(); + + // Return the allocatated memory + return p; + } +#endif // __WINS__ + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::Free() +// Frees the allocated memory +// ----------------------------------------------------------------------------- +// +TAny RAnalyzeToolAllocator::Free( TAny* aPtr ) + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::Free()" ); + + // Acquire the mutex + iMutex.Wait(); + + // Don't collect or log data if storage server not open or logging mode not fast xti. + if ( iStorageServerOpen || iLogOption == EATLogToXtiFast ) + { + // Reset the callstack + iFreeCallStack.Reset(); + + // Check if XTI logging mode because free call stack is not used in other log options. + if ( (iLogOption == EATUseDefault || iLogOption == EATLogToXti || iLogOption == EATLogToXtiFast ) + && iFreeMaxCallStack > 0 ) + { + // Find the current thread callstack start address + TUint32 stackstart( 0 ); + TBool found( FindCurrentThreadStack( stackstart ) ); + LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found ); + TUint32 _sp; + + #ifdef __WINS__ + __asm + { + mov [_sp], esp + } + #else + _sp = __current_sp(); + #endif + + // Get codeblocks count + TInt blocksCount( iCodeblocks.Count() ); + TUint arrayCounter = 0; + + for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348 + { + TUint32 addr = (TUint32) *( (TUint32*) i ); + if ( ! IsAddressLoadedCode( addr ) ) + continue; + for ( TInt j = 0; j < blocksCount; j++ ) + { + if ( iCodeblocks[j].CheckAddress( addr ) ) + { + // To avoid recursive call to ReAlloc specifying granularity + // Add address to the callstack + iFreeCallStack[arrayCounter] = addr; + arrayCounter++; + break; + } + } + if ( arrayCounter == KATMaxFreeCallstackLength || + arrayCounter == iFreeMaxCallStack ) + { + break; + } + } + LOGSTR2( "ATMH > iFreeCallStack count ( %i )", arrayCounter ); + } + + // Log freed memory. + if ( iLogOption == EATLogToXtiFast ) + { + // Using fast xti. + ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack ); + } + else + { + // Using storage server. + TInt err( iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack ) ); + if ( err != KErrNone ) + { + LOGSTR2( "ATMH > LogMemoryFreed err( %i )", err ); + } + } + } + + // Free the memory using original allocator + iAllocator->Free( aPtr ); + + LOGSTR2( "ATMH RAnalyzeToolAllocator::Free() - aPtr: %x", (TUint32)aPtr ); + + // Release the mutex + iMutex.Signal(); + } + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::Open() +// Opens this heap for shared access. Opening the heap increases +// the heap's access count by one. +// ----------------------------------------------------------------------------- +// +TInt RAnalyzeToolAllocator::Open() + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::Open()"); + + // Acquire the mutex + iMutex.Wait(); + + // Share the memory using original allocator + TInt error = iAllocator->Open(); + + // If everything is OK add thread to the array which use this allocator + if ( KErrNone == error ) + { + TThreadParamsBuf params; + params().iThreadId = RThread().Id().operator TUint(); + error = iAnalyzeTool.ThreadStack( params ); + + __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) ); + + if ( KErrNone == error ) + { + LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress ); + LOGSTR2( "ATMH Thread stack size: %x", params().iStackSize ); + iThreadArray.Append( TThreadStack( RThread().Id(), + params().iStackAddress + params().iStackSize ) ); + } + } + + // Release the mutex + iMutex.Signal(); + + // Return the error code + return error; + } + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::Close() +// Closes this shared heap. Closing the heap decreases the heap's +// access count by one. +// ----------------------------------------------------------------------------- +// +void RAnalyzeToolAllocator::Close() + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::Close()" ); + + // Acquire the mutex + iMutex.Wait(); + + // Close the memory using original allocator + iAllocator->Close(); + + TInt count = iThreadArray.Count(); + + // Iterate through array of threads to remove current thread + for ( TInt i = 0; i < count; i++ ) + { + // Check if this is current thread + if ( iThreadArray[ i ].Match() ) + { + // Remove the thread + iThreadArray.Remove( i ); + break; + } + } + + // Release the mutex + iMutex.Signal(); + } + +#ifdef __WINS__ + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::ReAlloc() +// Increases or decreases the size of an existing cell. +// ----------------------------------------------------------------------------- +// +TAny* RAnalyzeToolAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode ) + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc()" ); + + // Acquire the mutex + iMutex.Wait(); + + // Realloc the memory using original allocator + TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode ); + + // NULL addresses are not in a process under test + if ( ptr && !( aMode & ENeverMove ) ) + { + LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aPtr: %x, ptr: %x", + (TUint32)aPtr, (TUint32)ptr ); + LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aSize: %i, aMode: %i", + aSize, aMode ); + + // Don't collect or log data if storage server not open or logging mode fast xti. + if ( iStorageServerOpen || iLogOption == EATLogToXtiFast ) + { + // Reset the callstack + iReCallStack.Reset(); + + // Find the current thread callstack start address + TUint32 stackstart( 0 ); + TBool found( FindCurrentThreadStack( stackstart ) ); + LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found ); + + // Get current sp + TUint32 _sp( 0 ); + __asm + { + mov [_sp], esp + } + + // Get codeblocks count + TInt blocksCount( iCodeblocks.Count() ); + TInt error( KErrNone ); + TUint arrayCounter = 0; + + for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348 + { + TUint32 addr = (TUint32) *( (TUint32*) i ); + if ( ! IsAddressLoadedCode( addr ) ) + continue; + for ( TInt j = 0; j < blocksCount; j++ ) + { + if ( iCodeblocks[j].CheckAddress( addr ) ) + { + // To avoid recursive call to ReAlloc specifying granularity + // Add address to the callstack + iReCallStack[arrayCounter] = addr; + arrayCounter++; + break; + } + } + if ( arrayCounter == KATMaxCallstackLength || + arrayCounter == iAllocMaxCallStack ) + { + LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter ); + break; + } + } + + // No need to report free if the aPtr was NULL + if ( aPtr != NULL ) + { + // Reset the free callstack + iFreeCallStack.Reset(); + + // if XTI logging mode(s) we also log call stack in free. + if ( ( iLogOption == EATUseDefault || iLogOption == EATLogToXti || iLogOption == EATLogToXtiFast ) + && iFreeMaxCallStack > 0 ) + { + for ( TInt i = 0; i < arrayCounter; i++ ) + { + if ( i == KATMaxFreeCallstackLength || i == iFreeMaxCallStack ) + { + break; + } + iFreeCallStack[i] = iReCallStack[i]; + } + } + + // Try to remove old address from the storage server's + // leak array. If found it's removed from the array because system frees + // old address directly in the RHeap in ReAlloc case. + if ( iLogOption == EATLogToXtiFast ) + { + ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack ); + } + else + { + iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack ); + } + } + + // Log the memory allocation information + if ( iLogOption == EATLogToXtiFast ) + { + // Using fast xti. + ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iFreeCallStack, aSize); + } + else + { + // Using storage server. + error = iStorageServer.LogMemoryAllocated( (TUint32) ptr, + iReCallStack, + aSize ); + if ( KErrNone != error ) + { + LOGSTR2( "ATMH LogMemoryAllocated ReAlloc error %i", error ); + switch ( error ) + { + case KErrNoMemory: + LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - KErrNoMemory case" ); + if ( iStorageServerOpen ) + { + iStorageServerOpen = EFalse; + LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - close iStorageServer" ); + iStorageServer.Close(); + } + break; + } + } + } + } + } + + // Release the mutex + iMutex.Signal(); + + // Return pointer to the reallocated cell + return ptr; + } + +#else + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::ReAlloc() +// Increases or decreases the size of an existing cell. +// ----------------------------------------------------------------------------- +// +TAny* RAnalyzeToolAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode ) + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc()" ); + + // Acquire the mutex + iMutex.Wait(); + + // Realloc the memory using original allocator + TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode ); + + // NULL addresses are not in a process under test + if ( ptr && !( aMode & ENeverMove ) ) + { + LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aPtr: %x, ptr: %x", + (TUint32)aPtr, (TUint32)ptr ); + LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aSize: %i, aMode: %i", + aSize, aMode ); + + // Don't collect or log data if storage server not open or logging mode fast xti. + if ( iStorageServerOpen || iLogOption == EATLogToXtiFast ) + { + // Reset the callstack + iReCallStack.Reset(); + + // Find the current thread callstack start address + TUint32 stackstart( 0 ); + TBool found( FindCurrentThreadStack( stackstart ) ); + LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found ); + + // Get codeblocks count + TInt blocksCount( iCodeblocks.Count() ); + TInt error( KErrNone ); + TUint arrayCounter = 0; + + for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348 + { + for ( TInt j = 0; j < blocksCount; j++ ) + { + if ( iCodeblocks[j].CheckAddress( (TUint32) *( (TUint32*) i ) ) ) + { + // To avoid recursive call to ReAlloc specifying granularity + // Add address to the callstack + iReCallStack[arrayCounter] = ( (TUint32) *( (TUint32*) i ) ); + arrayCounter++; + break; + } + } + if ( arrayCounter == KATMaxCallstackLength || + arrayCounter == iAllocMaxCallStack ) + { + LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter ); + break; + } + } + + // No need to report free if the aPtr was NULL + if ( aPtr != NULL ) + { + // Reset the free callstack + iFreeCallStack.Reset(); + + // if XTI logging mode(s) we also log call stack with free. + if ( ( iLogOption == EATUseDefault || iLogOption == EATLogToXti || iLogOption == EATLogToXtiFast ) + && iFreeMaxCallStack > 0 ) + { + for ( TInt i = 0; i < arrayCounter; i++ ) + { + if ( i == iFreeCallStack.Count() ) + { + break; + } + iFreeCallStack[i] = iReCallStack[i]; + } + } + + // Try to remove old address from the storage server's + // leak array. If found it's removed from the array because system frees + // old address directly in the RHeap in ReAlloc case. + if ( iLogOption == EATLogToXtiFast ) + { + ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack ); + } + else + { + iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack ); + } + } + + // Log the memory allocation information + if ( iLogOption == EATLogToXtiFast ) + { + // Using fast xti. + ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iReCallStack, aSize ); + } + else + { + // Using storage server. + error = iStorageServer.LogMemoryAllocated( (TUint32) ptr, + iReCallStack, + aSize ); + if ( KErrNone != error ) + { + LOGSTR2( "ATMH LogMemoryAllocated ReAlloc error %i", error ); + switch ( error ) + { + case KErrNoMemory: + LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - KErrNoMemory case" ); + if ( iStorageServerOpen ) + { + iStorageServerOpen = EFalse; + LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - close iStorageServer" ); + iStorageServer.Close(); + } + break; + } + } + } + } + } + + // Release the mutex + iMutex.Signal(); + + // Return pointer to the reallocated cell + return ptr; + } + +#endif // __WINS__ + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::Compress() +// The function frees excess committed space from the top of the heap. +// The size of the heap is never reduced below the minimum size +// specified during creation of the heap. +// ----------------------------------------------------------------------------- +// +TInt RAnalyzeToolAllocator::Compress() + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::Compress()" ); + + // Acquire the mutex + iMutex.Wait(); + + // Compress the memory using original allocator + TInt compress = iAllocator->Compress(); + + // Release the mutex + iMutex.Signal(); + + // Return the space reclaimed + return compress; + } + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::Reset() +// Frees all allocated cells on this heap. +// ----------------------------------------------------------------------------- +// +void RAnalyzeToolAllocator::Reset() + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::Reset()" ); + + // Acquire the mutex + iMutex.Wait(); + + // Reset the memory using original allocator + iAllocator->Reset(); + + // Release the mutex + iMutex.Signal(); + } + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::AllocSize() +// Gets the number of cells allocated on this heap, and +// the total space allocated to them. +// ----------------------------------------------------------------------------- +// +TInt RAnalyzeToolAllocator::AllocSize( TInt& aTotalAllocSize ) const + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::AllocSize()" ); + + // Acquire the mutex + iMutex.Wait(); + + // Acquire the memory information using original allocator + TInt size = iAllocator->AllocSize( aTotalAllocSize ); + + // Release the mutex + iMutex.Signal(); + + // Return the number of cells allocated on this heap. + return size; + } + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::Available() +// Gets the total free space currently available on the heap and the +// space available in the largest free block. The space available +// represents the total space which can be allocated. Note that +// compressing the heap may reduce the total free space available +// and the space available in the largest free block. +// ----------------------------------------------------------------------------- +// +TInt RAnalyzeToolAllocator::Available( TInt& aBiggestBlock ) const + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::Available()" ); + + // Acquire the mutex + iMutex.Wait(); + + // Acquire the memory information using original allocator + TInt available = iAllocator->Available( aBiggestBlock ); + + // Release the mutex + iMutex.Signal(); + + // Return the total free space currently available on the heap + return available; + } + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::AllocLen() +// Gets the length of the available space in the specified +// allocated cell. +// ----------------------------------------------------------------------------- +// +TInt RAnalyzeToolAllocator::AllocLen( const TAny* aCell ) const + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::AllocLen()" ); + + // Acquire the mutex + iMutex.Wait(); + + // Acquire the memory information using original allocator + TInt len = iAllocator->AllocLen( aCell ); + + // Release the mutex + iMutex.Signal(); + + // Return the length of the available space in the allocated cell. + return len; + } + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::DebugFunction() +// Invocates specified debug funtionality. +// ----------------------------------------------------------------------------- +// +TInt RAnalyzeToolAllocator::DebugFunction( TInt aFunc, TAny* a1, TAny* a2 ) + { + LOGSTR2( "ATMH RAnalyzeToolAllocator::DebugFunction() %i", aFunc ); + + // Acquire the mutex + iMutex.Wait(); + + // Invocate debug funtion using original allocator + TInt debug = iAllocator->DebugFunction( aFunc, a1, a2 ); + + switch( aFunc ) + { + case EMarkEnd: + { + // Disables the __UHEAP_MARKEND macro + LOGSTR1( "ATMH __UHEAP_MARKEND macro called" ); + if ( debug > 0 ) + { + LOGSTR2( "ATMH __UHEAP_MARKEND detects leaks: %d", debug ); + // Because there is leaks the alloc panic will occur but + // lets return a zero to pretend that everything is OK + debug = 0; + } + } + break; + + default: + { + } + break; + } + + // Release the mutex + iMutex.Signal(); + + // Return information of the debug function success + return debug; + } + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::Extension_() +// Extension function +// ----------------------------------------------------------------------------- +// +TInt RAnalyzeToolAllocator::Extension_( TUint aExtensionId, TAny*& a0, + TAny* a1 ) + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::Extension_()" ); + + // Acquire the mutex + iMutex.Wait(); + + // Invocate extension funtion using original allocator + TInt ext = RAllocator::Extension_( aExtensionId, a0, a1 ); + + // Release the mutex + iMutex.Signal(); + + // Return information of the extension function success + return ext; + } + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::ShareHeap() +// Share heap with other thread +// ----------------------------------------------------------------------------- +// +void RAnalyzeToolAllocator::ShareHeap() + { + LOGSTR1( "ATMH RAnalyzeToolAllocator::ShareHeap()" ); + + // Call the overwrited Open function + Open(); + } + +// ----------------------------------------------------------------------------- +// RAnalyzeToolAllocator::FindCurrentThreadStack() +// Find the current thread which is using the heap +// ----------------------------------------------------------------------------- +// +TBool RAnalyzeToolAllocator::FindCurrentThreadStack( TUint32& aStackStart ) + { + LOGSTR2( "ATMH RAnalyzeToolAllocator::FindCurrentThreadStack(), count( %i )", + iThreadArray.Count() ); + + // Flag for indicating that right thread has been found + TBool found( EFalse ); + // If threre is only one thread it must be the right thread + if ( iThreadArray.Count() == KThreadCount ) + { + if ( !iThreadArray[ 0 ].ThreadStackStart( aStackStart ) ) + { + // This MUST BE the right thread + //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) ); + } + else if ( iThreadArray[ 0 ].ThreadStackStart( aStackStart ) ) + { + found = ETrue; + } + } + else + { + // Iterate through array to find right thread + TInt count( iThreadArray.Count() ); + + for ( TInt i = 0; i < count; i++ ) + { + // Check if this is the right thread + if ( iThreadArray[ i ].ThreadStackStart( aStackStart ) ) + { + // Right thread found. Mark the flag + found = ETrue; + break; + } + } + // If right thread was not found the panic must be raised + if ( !found ) + { + //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) ); + } + } + return found; + } + +// End of File