perfsrv/analyzetool/dynamicmemoryhook/src/analyzetoolallocator.cpp
changeset 51 98307c651589
equal deleted inserted replaced
42:0ff24a8f6ca2 51:98307c651589
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Definitions for the class RAnalyzeToolAllocator.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "analyzetoolallocator.h"
       
    20 #include "analyzetoolmemoryallocator.h"
       
    21 #include "atlog.h"
       
    22 #include "analyzetoolpanics.pan"
       
    23 #include "analyzetoolfastlog.h"
       
    24 #include <e32svr.h>
       
    25 
       
    26 // CONSTANTS
       
    27 
       
    28 // Length of the callstack address
       
    29 const TUint32 KAddressLength = 4;
       
    30 
       
    31 // Thread count
       
    32 const TInt KThreadCount = 1;
       
    33 
       
    34 // -----------------------------------------------------------------------------
       
    35 // RAnalyzeToolAllocator::RAnalyzeToolAllocator()
       
    36 // C++ default constructor can NOT contain any code, that
       
    37 // might leave.
       
    38 // -----------------------------------------------------------------------------
       
    39 //
       
    40 RAnalyzeToolAllocator::RAnalyzeToolAllocator( TBool aNotFirst,
       
    41                                               RArray<TCodeblock>& aCodeblocks, 
       
    42                                               RMutex& aMutex,
       
    43                                               TUint aProcessId,
       
    44                                               RAnalyzeTool& aAnalyzeTool,
       
    45                                               TUint32 aLogOption,
       
    46                                               TUint32 aAllocCallStackSize,
       
    47                                               TUint32 aFreeCallStackSize,
       
    48                                               RATFileLog& aLogFile ) :
       
    49     RAnalyzeToolMemoryAllocator( aNotFirst ),
       
    50     iCodeblocks( aCodeblocks ), 
       
    51     iMutex( aMutex ),
       
    52     iProcessId( aProcessId ),
       
    53     iThreadArray( KATMaxCallstackLength ),
       
    54     iAnalyzeTool( aAnalyzeTool ),
       
    55     iLogOption( aLogOption ),
       
    56     iAllocMaxCallStack( aAllocCallStackSize ),
       
    57     iFreeMaxCallStack( aFreeCallStackSize ),
       
    58     iLogFile ( aLogFile )
       
    59     {
       
    60     LOGSTR1( "ATMH RAnalyzeToolAllocator::RAnalyzeToolAllocator()" );
       
    61     
       
    62     // Append thread to array of the users of this allocator
       
    63     TThreadParamsBuf params;
       
    64     params().iThreadId = RThread().Id().operator TUint();
       
    65     TInt error = iAnalyzeTool.ThreadStack( params );
       
    66     if ( KErrNone == error )
       
    67         {
       
    68         LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
       
    69         LOGSTR2( "ATMH Thread stack size:    %x", params().iStackSize );
       
    70         error = iThreadArray.Append( TThreadStack( RThread().Id(), 
       
    71                              params().iStackAddress + params().iStackSize ) );
       
    72 
       
    73         if ( iLogOption == EATLogToTraceFast )
       
    74         	{
       
    75             // log thread added
       
    76             ATFastLogThreadStarted( aProcessId, RThread().Id().operator TUint() ); 
       
    77         	}
       
    78         else if ( iLogOption == EATLogToFile )
       
    79         	{
       
    80             iLogFile.ATFileLogThreadStarted( RThread().Id().operator TUint() );
       
    81         	}
       
    82         }
       
    83     
       
    84     __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) ); 
       
    85     }
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // RAnalyzeToolAllocator::~RAnalyzeToolAllocator()
       
    89 // Destructor.
       
    90 // -----------------------------------------------------------------------------
       
    91 //
       
    92 RAnalyzeToolAllocator::~RAnalyzeToolAllocator()
       
    93     {
       
    94     LOGSTR1( "ATMH RAnalyzeToolAllocator::~RAnalyzeToolAllocator()" );
       
    95     
       
    96     for( TInt i=0; i<iThreadArray.Count(); i++)
       
    97     	{
       
    98         // log thread removed
       
    99         if ( iLogOption == EATLogToTraceFast )
       
   100         	{
       
   101             ATFastLogThreadEnded( RProcess().Id().operator TUint(), RThread().Id().operator TUint() ); 
       
   102             }
       
   103         else if ( iLogOption == EATLogToFile )
       
   104         	{
       
   105             iLogFile.ATFileLogThreadEnded( RThread().Id().operator TUint() );
       
   106         	}
       
   107          }
       
   108     
       
   109     
       
   110     // Close the thread array 
       
   111     iThreadArray.Close();
       
   112     }
       
   113     
       
   114 // -----------------------------------------------------------------------------
       
   115 // RAnalyzeToolAllocator::Uninstall()
       
   116 // Uninstalls the current allocator
       
   117 // -----------------------------------------------------------------------------
       
   118 //
       
   119 void RAnalyzeToolAllocator::Uninstall()
       
   120     {
       
   121     LOGSTR1( "ATMH RAnalyzeToolAllocator::Uninstall()" );
       
   122 
       
   123     // Switch back to the original allocator
       
   124     SwitchOriginalAllocator();
       
   125     
       
   126     // Check if this is shared allocator between threads
       
   127     if ( iThreadArray.Count() > KThreadCount )
       
   128         {
       
   129         // Close the shared allocator
       
   130         Close();
       
   131         return;
       
   132         }
       
   133 
       
   134 #if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
       
   135     #ifndef __WINS__ 
       
   136     // Remove dummy Tls handle
       
   137     UserSvr::DllFreeTls( KDummyHandle );
       
   138     #endif
       
   139 #endif
       
   140     
       
   141     // Since this is the last thread using this allocator it can be deleted
       
   142     delete this;
       
   143     }
       
   144 
       
   145 #ifdef __WINS__
       
   146 
       
   147 // -----------------------------------------------------------------------------
       
   148 // RAnalyzeToolAllocator::Alloc() WINS version
       
   149 // Allocates a cell of specified size from the heap.
       
   150 // -----------------------------------------------------------------------------
       
   151 //
       
   152 UEXPORT_C TAny* RAnalyzeToolAllocator::Alloc( TInt aSize )
       
   153     {
       
   154     LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc()" );
       
   155     
       
   156     // Acquire the mutex
       
   157     iMutex.Wait();
       
   158     
       
   159     // get thread ID
       
   160     TUint threadId = RThread().Id();
       
   161     // Alloc memory from the original allocator
       
   162     TAny* p = iAllocator->Alloc( aSize );
       
   163     
       
   164     LOGSTR3( "ATMH RAnalyzeToolAllocator::Alloc() - aSize: %i, address: %x", 
       
   165              aSize,  (TUint32) p );
       
   166     
       
   167 	// Reset the callstack
       
   168 	iCallStack.Reset();
       
   169 
       
   170 	// Find the current thread callstack start address
       
   171 	TUint32 stackstart( 0 );
       
   172 	TBool found( FindCurrentThreadStack( stackstart ) );
       
   173 	LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   174 	
       
   175 	TUint32 _sp;
       
   176 	__asm
       
   177 		{
       
   178 		mov [_sp], esp
       
   179 		}
       
   180 	
       
   181 	// Get codeblocks count
       
   182 	TInt blocksCount( iCodeblocks.Count() );
       
   183 	TInt error( KErrNone );
       
   184 	TUint arrayCounter = 0;
       
   185 	
       
   186 	for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   187 		{
       
   188 		TUint32 addr = (TUint32) *( (TUint32*) i );
       
   189 		if ( ! IsAddressLoadedCode( addr ) )
       
   190 			continue;
       
   191 		for ( TInt j = 0; j < blocksCount; j++ )
       
   192 			{
       
   193 			if ( iCodeblocks[j].CheckAddress( addr ) )
       
   194 				{
       
   195 				// To avoid recursive call to ReAlloc specifying granularity
       
   196 				// Add address to the callstack
       
   197 				iCallStack[arrayCounter] = ( addr );
       
   198 				arrayCounter++;
       
   199 				break;
       
   200 				}
       
   201 			}
       
   202 		if ( arrayCounter == KATMaxCallstackLength ||
       
   203 			 arrayCounter == iAllocMaxCallStack )
       
   204 			{
       
   205 			LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   206 			break;
       
   207 			}
       
   208 		}
       
   209 	// Log the memory allocation information
       
   210 	if ( iLogOption == EATLogToTraceFast )
       
   211 		{
       
   212 		// Using fast mode.
       
   213 		ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize, threadId );
       
   214 		}
       
   215 	else if ( iLogOption == EATLogToFile )
       
   216 		{
       
   217 		iLogFile.ATFileLogMemoryAllocated( (TUint32) p, iCallStack, aSize, threadId );
       
   218 		}
       
   219    
       
   220     // Release the mutex
       
   221     iMutex.Signal();
       
   222     
       
   223     return p;
       
   224     }
       
   225 #else
       
   226 
       
   227 // -----------------------------------------------------------------------------
       
   228 // RAnalyzeToolAllocator::Alloc() ARMV5 version
       
   229 // Allocates a cell of specified size from the heap.
       
   230 // -----------------------------------------------------------------------------
       
   231 //
       
   232 TAny* RAnalyzeToolAllocator::Alloc( TInt aSize )
       
   233     {
       
   234     LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc()" );
       
   235     
       
   236     // Acquire the mutex
       
   237     iMutex.Wait();
       
   238     
       
   239     // get thread ID
       
   240     TUint threadId = RThread().Id();
       
   241         
       
   242     // Alloc memory from the original allocator
       
   243     TAny* p = iAllocator->Alloc( aSize );
       
   244         
       
   245 
       
   246 	// Reset the callstack
       
   247 	iCallStack.Reset(); 
       
   248 	
       
   249 	// Find the current thread callstack start address
       
   250 	TUint32 stackstart( 0 );
       
   251 	TBool found( FindCurrentThreadStack( stackstart ) );
       
   252 	LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   253 	
       
   254 	// Get codeblocks count
       
   255 	TInt blocksCount( iCodeblocks.Count() );
       
   256 	TUint arrayCounter = 0;
       
   257 	
       
   258 	for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   259 		{
       
   260 		TUint32 addr = (TUint32) *( (TUint32*) i );
       
   261 		if ( ! IsAddressLoadedCode( addr ) )
       
   262 			continue;
       
   263 		for ( TInt j = 0; j < blocksCount; j++ )
       
   264 			{
       
   265 			if ( iCodeblocks[j].CheckAddress( addr ) )
       
   266 				{
       
   267 				// To avoid recursive call to ReAlloc specifying granularity
       
   268 				// Add address to the callstack
       
   269 				iCallStack[arrayCounter] = ( addr );
       
   270 				arrayCounter++;
       
   271 				break;
       
   272 				}
       
   273 			}
       
   274 		if ( arrayCounter == KATMaxCallstackLength ||
       
   275 			 arrayCounter == iAllocMaxCallStack )
       
   276 			{
       
   277 			LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   278 			break;
       
   279 			}
       
   280 		}
       
   281 	// Log the memory allocation information
       
   282 	if ( iLogOption == EATLogToTraceFast )
       
   283 		{
       
   284 		// Fast mode.
       
   285 		ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize, threadId );
       
   286 		} 
       
   287 	else if ( iLogOption == EATLogToFile )
       
   288 		{
       
   289 	    iLogFile.ATFileLogMemoryAllocated( (TUint32) p, iCallStack, aSize, threadId );
       
   290 		}
       
   291 
       
   292  
       
   293     // Release the mutex
       
   294     iMutex.Signal(); 
       
   295     
       
   296     // Return the allocatated memory
       
   297     return p;
       
   298     }
       
   299 #endif // __WINS__
       
   300 
       
   301 // -----------------------------------------------------------------------------
       
   302 // RAnalyzeToolAllocator::Free()
       
   303 // Frees the allocated memory
       
   304 // -----------------------------------------------------------------------------
       
   305 //
       
   306 TAny RAnalyzeToolAllocator::Free( TAny* aPtr )
       
   307     {
       
   308     LOGSTR1( "ATMH RAnalyzeToolAllocator::Free()" );
       
   309 
       
   310     // Acquire the mutex
       
   311     iMutex.Wait();
       
   312     
       
   313     // get thread ID
       
   314     TUint threadId = RThread().Id();
       
   315     
       
   316 	// Reset the callstack
       
   317 	iFreeCallStack.Reset();
       
   318 	
       
   319 	if ( iFreeMaxCallStack > 0 )
       
   320 		{
       
   321 		// Find the current thread callstack start address
       
   322 		TUint32 stackstart( 0 );
       
   323 		TBool found( FindCurrentThreadStack( stackstart ) );
       
   324 		LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   325 		TUint32 _sp;
       
   326 		
       
   327 		#ifdef __WINS__
       
   328 			__asm
       
   329 				{
       
   330 				mov [_sp], esp
       
   331 				}
       
   332 		#else
       
   333 			_sp = __current_sp();
       
   334 		#endif
       
   335 		
       
   336 		// Get codeblocks count
       
   337 		TInt blocksCount( iCodeblocks.Count() );
       
   338 		TUint arrayCounter = 0;
       
   339 	
       
   340 		for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   341 			{
       
   342 			TUint32 addr = (TUint32) *( (TUint32*) i );
       
   343 			if ( ! IsAddressLoadedCode( addr ) )
       
   344 				continue;
       
   345 			for ( TInt j = 0; j < blocksCount; j++ )
       
   346 				{
       
   347 				if ( iCodeblocks[j].CheckAddress( addr ) )
       
   348 					{
       
   349 					// To avoid recursive call to ReAlloc specifying granularity
       
   350 					// Add address to the callstack
       
   351 					iFreeCallStack[arrayCounter] = addr;
       
   352 					arrayCounter++;
       
   353 					break;
       
   354 					}
       
   355 				}
       
   356 			if ( arrayCounter == KATMaxFreeCallstackLength ||
       
   357 				 arrayCounter == iFreeMaxCallStack )
       
   358 				{
       
   359 				break;
       
   360 				}
       
   361 			}
       
   362 		LOGSTR2( "ATMH > iFreeCallStack count ( %i )", arrayCounter );
       
   363 		}
       
   364 	
       
   365 	// Log freed memory.
       
   366 	if ( iLogOption == EATLogToTraceFast )
       
   367 		{
       
   368 		// Using fast mode.
       
   369 		ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack, threadId );
       
   370 		} 
       
   371 	else if ( iLogOption == EATLogToFile )
       
   372 		{
       
   373 		iLogFile.ATFileLogMemoryFreed( (TUint32) aPtr, iFreeCallStack, threadId );
       
   374 		}
       
   375     
       
   376     // Free the memory using original allocator
       
   377     iAllocator->Free( aPtr ); 
       
   378     
       
   379     LOGSTR2( "ATMH RAnalyzeToolAllocator::Free() - aPtr: %x", (TUint32)aPtr );
       
   380     
       
   381     // Release the mutex
       
   382     iMutex.Signal();
       
   383     }
       
   384 
       
   385 // -----------------------------------------------------------------------------
       
   386 // RAnalyzeToolAllocator::Open()
       
   387 // Opens this heap for shared access. Opening the heap increases 
       
   388 // the heap's access count by one.
       
   389 // -----------------------------------------------------------------------------
       
   390 //
       
   391 TInt RAnalyzeToolAllocator::Open()
       
   392     {
       
   393     LOGSTR1( "ATMH RAnalyzeToolAllocator::Open()");
       
   394     
       
   395     // Acquire the mutex
       
   396     iMutex.Wait();
       
   397     
       
   398     // Share the memory using original allocator
       
   399     TInt error = iAllocator->Open();
       
   400     
       
   401     // If everything is OK add thread to the array which use this allocator
       
   402     if ( KErrNone == error )
       
   403         {
       
   404         TThreadParamsBuf params;
       
   405         params().iThreadId = RThread().Id().operator TUint();
       
   406         error = iAnalyzeTool.ThreadStack( params );
       
   407 
       
   408         __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) );
       
   409 
       
   410         if ( KErrNone == error )
       
   411             {
       
   412             LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
       
   413             LOGSTR2( "ATMH Thread stack size:    %x", params().iStackSize );
       
   414             iThreadArray.Append( TThreadStack( RThread().Id(), 
       
   415                     params().iStackAddress + params().iStackSize ) );
       
   416             if ( iLogOption == EATLogToTraceFast )
       
   417             	{
       
   418                 // log thread added
       
   419                 ATFastLogThreadStarted( RProcess().Id().operator TUint(), RThread().Id().operator TUint()); 
       
   420             	}
       
   421             else if ( iLogOption == EATLogToFile )
       
   422 				{
       
   423 				iLogFile.ATFileLogThreadStarted( RThread().Id().operator TUint() );
       
   424 				}
       
   425             }
       
   426         }
       
   427     
       
   428     // Release the mutex
       
   429     iMutex.Signal();
       
   430     
       
   431     // Return the error code
       
   432     return error;
       
   433     }
       
   434 
       
   435 // -----------------------------------------------------------------------------
       
   436 // RAnalyzeToolAllocator::Close()
       
   437 // Closes this shared heap. Closing the heap decreases the heap's 
       
   438 // access count by one.
       
   439 // -----------------------------------------------------------------------------
       
   440 //
       
   441 void RAnalyzeToolAllocator::Close()
       
   442     {
       
   443     LOGSTR1( "ATMH RAnalyzeToolAllocator::Close()" );
       
   444     
       
   445     // Acquire the mutex
       
   446     iMutex.Wait();
       
   447     
       
   448     // Close the memory using original allocator
       
   449     iAllocator->Close();
       
   450     
       
   451     TInt count = iThreadArray.Count();
       
   452     
       
   453     // Iterate through array of threads to remove current thread
       
   454     for ( TInt i = 0; i < count; i++ )
       
   455         {
       
   456         // Check if this is current thread
       
   457         if ( iThreadArray[ i ].Match() )
       
   458             {
       
   459             // Remove the thread
       
   460             iThreadArray.Remove( i );
       
   461             if ( iLogOption == EATLogToTraceFast )
       
   462             	{
       
   463                 // log thread removed
       
   464                 ATFastLogThreadEnded( RProcess().Id().operator TUint(), RThread().Id().operator TUint() ); 
       
   465             	}
       
   466             else if ( iLogOption == EATLogToFile )
       
   467 				{
       
   468 				iLogFile.ATFileLogThreadEnded( RThread().Id().operator TUint() );
       
   469 				}
       
   470             
       
   471             break;
       
   472             }
       
   473         }
       
   474     
       
   475     // Release the mutex
       
   476     iMutex.Signal();
       
   477     }
       
   478 
       
   479 #ifdef __WINS__
       
   480 
       
   481 // -----------------------------------------------------------------------------
       
   482 // RAnalyzeToolAllocator::ReAlloc()
       
   483 // Increases or decreases the size of an existing cell.
       
   484 // -----------------------------------------------------------------------------
       
   485 //
       
   486 TAny* RAnalyzeToolAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
       
   487     {
       
   488     LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc()" );
       
   489 
       
   490     // Acquire the mutex
       
   491     iMutex.Wait();
       
   492     
       
   493     // get thread ID
       
   494     TUint threadId = RThread().Id();
       
   495 
       
   496     // Realloc the memory using original allocator
       
   497     TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
       
   498     
       
   499     // NULL addresses are not in a process under test
       
   500     if ( ptr && !( aMode & ENeverMove ) )
       
   501         {
       
   502         LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aPtr: %x, ptr: %x", 
       
   503                 (TUint32)aPtr, (TUint32)ptr );
       
   504         LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aSize: %i, aMode: %i", 
       
   505                 aSize, aMode );
       
   506 
       
   507 
       
   508 		// Reset the callstack
       
   509 		iReCallStack.Reset(); 
       
   510 
       
   511 		// Find the current thread callstack start address
       
   512 		TUint32 stackstart( 0 ); 
       
   513 		TBool found( FindCurrentThreadStack( stackstart ) );
       
   514 		LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   515 		
       
   516 		// Get current sp
       
   517 		TUint32 _sp( 0 );
       
   518 		__asm
       
   519 			{
       
   520 			mov [_sp], esp
       
   521 			}
       
   522 		
       
   523 		// Get codeblocks count
       
   524 		TInt blocksCount( iCodeblocks.Count() );
       
   525 		TInt error( KErrNone );
       
   526 		TUint arrayCounter = 0;
       
   527 		
       
   528 		for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   529 			{
       
   530 			TUint32 addr = (TUint32) *( (TUint32*) i );
       
   531 			if ( ! IsAddressLoadedCode( addr ) )
       
   532 				continue;
       
   533 			for ( TInt j = 0; j < blocksCount; j++ )
       
   534 				{
       
   535 				if ( iCodeblocks[j].CheckAddress( addr ) )
       
   536 					{
       
   537 					// To avoid recursive call to ReAlloc specifying granularity
       
   538 					// Add address to the callstack
       
   539 					iReCallStack[arrayCounter] = addr;
       
   540 					arrayCounter++;
       
   541 					break;
       
   542 					}
       
   543 				}
       
   544 			if ( arrayCounter == KATMaxCallstackLength || 
       
   545 				 arrayCounter == iAllocMaxCallStack )
       
   546 				{
       
   547 				LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   548 				break;
       
   549 				}
       
   550 			}
       
   551 
       
   552 		if ( iLogOption == EATLogToTraceFast )
       
   553 			{
       
   554 			// Using fast logging mode.
       
   555 			ATFastLogMemoryReallocated( iProcessId, (TUint32) aPtr, (TUint32) ptr, iReCallStack, aSize, threadId );
       
   556 			}
       
   557 		else if ( iLogOption == EATLogToFile )
       
   558 			{
       
   559 			iLogFile.ATFileLogMemoryReallocated( (TUint32) aPtr, (TUint32) ptr, iReCallStack, aSize, threadId );
       
   560 			}	
       
   561 		}
       
   562     
       
   563     // Release the mutex
       
   564     iMutex.Signal();
       
   565 
       
   566     // Return pointer to the reallocated cell
       
   567     return ptr; 
       
   568     }
       
   569 
       
   570 #else
       
   571 
       
   572 // -----------------------------------------------------------------------------
       
   573 // RAnalyzeToolAllocator::ReAlloc()
       
   574 // Increases or decreases the size of an existing cell.
       
   575 // -----------------------------------------------------------------------------
       
   576 //
       
   577 TAny* RAnalyzeToolAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
       
   578     {
       
   579     LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc()" );
       
   580 
       
   581     // Acquire the mutex
       
   582     iMutex.Wait();
       
   583     
       
   584     // get thread ID
       
   585     TUint threadId = RThread().Id();
       
   586 
       
   587     // Realloc the memory using original allocator
       
   588     TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
       
   589 
       
   590     // NULL addresses are not in a process under test
       
   591     if ( ptr && !( aMode & ENeverMove ) )
       
   592         {
       
   593         LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aPtr: %x, ptr: %x", 
       
   594                 (TUint32)aPtr, (TUint32)ptr );
       
   595         LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aSize: %i, aMode: %i", 
       
   596                 aSize, aMode );
       
   597 
       
   598 		// Reset the callstack
       
   599 		iReCallStack.Reset(); 
       
   600 
       
   601 		// Find the current thread callstack start address
       
   602 		TUint32 stackstart( 0 ); 
       
   603 		TBool found( FindCurrentThreadStack( stackstart ) );
       
   604 		LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
       
   605 		
       
   606 		// Get codeblocks count
       
   607 		TInt blocksCount( iCodeblocks.Count() );
       
   608 
       
   609 		TUint arrayCounter = 0;
       
   610 		
       
   611 		for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
       
   612 			{
       
   613 			TUint32 addr = (TUint32) *( (TUint32*) i );
       
   614 			if ( ! IsAddressLoadedCode( addr ) )
       
   615 				continue;
       
   616 			for ( TInt j = 0; j < blocksCount; j++ )
       
   617 				{
       
   618 				if ( iCodeblocks[j].CheckAddress( addr ) )
       
   619 					{
       
   620 					// To avoid recursive call to ReAlloc specifying granularity
       
   621 					// Add address to the callstack
       
   622 					iReCallStack[arrayCounter] = ( addr );
       
   623 					arrayCounter++;
       
   624 					break;
       
   625 					}
       
   626 				}
       
   627 			if ( arrayCounter == KATMaxCallstackLength || 
       
   628 				 arrayCounter == iAllocMaxCallStack )
       
   629 				{
       
   630 				LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
       
   631 				break;
       
   632 				}
       
   633 			}
       
   634 
       
   635 		if ( iLogOption == EATLogToTraceFast )
       
   636 			{
       
   637 			// Using fast logging mode.
       
   638 			ATFastLogMemoryReallocated( iProcessId, (TUint32) aPtr, (TUint32) ptr, iReCallStack, aSize, threadId );
       
   639 			}
       
   640 		else if ( iLogOption == EATLogToFile )
       
   641 			{
       
   642 			iLogFile.ATFileLogMemoryReallocated( (TUint32) aPtr, (TUint32) ptr, iReCallStack, aSize, threadId );
       
   643 			}
       
   644 		
       
   645 		
       
   646 		}
       
   647 
       
   648     // Release the mutex
       
   649     iMutex.Signal();
       
   650 
       
   651     // Return pointer to the reallocated cell
       
   652     return ptr; 
       
   653     }
       
   654 
       
   655 #endif // __WINS__
       
   656 
       
   657 // -----------------------------------------------------------------------------
       
   658 // RAnalyzeToolAllocator::Compress()
       
   659 // The function frees excess committed space from the top of the heap.
       
   660 // The size of the heap is never reduced below the minimum size 
       
   661 // specified during creation of the heap.
       
   662 // -----------------------------------------------------------------------------
       
   663 //
       
   664 TInt RAnalyzeToolAllocator::Compress()
       
   665     {
       
   666     LOGSTR1( "ATMH RAnalyzeToolAllocator::Compress()" );
       
   667 
       
   668     // Acquire the mutex
       
   669     iMutex.Wait();
       
   670 
       
   671     // Compress the memory using original allocator
       
   672     TInt compress = iAllocator->Compress();
       
   673 
       
   674     // Release the mutex
       
   675     iMutex.Signal();
       
   676 
       
   677     // Return the space reclaimed
       
   678     return compress;
       
   679     }
       
   680 
       
   681 // -----------------------------------------------------------------------------
       
   682 // RAnalyzeToolAllocator::Reset()
       
   683 // Frees all allocated cells on this heap. 
       
   684 // -----------------------------------------------------------------------------
       
   685 //
       
   686 void RAnalyzeToolAllocator::Reset()
       
   687     {
       
   688     LOGSTR1( "ATMH RAnalyzeToolAllocator::Reset()" );
       
   689 
       
   690     // Acquire the mutex
       
   691     iMutex.Wait();
       
   692 
       
   693     // Reset the memory using original allocator
       
   694     iAllocator->Reset();
       
   695 
       
   696     // Release the mutex
       
   697     iMutex.Signal();
       
   698     }
       
   699 
       
   700 // -----------------------------------------------------------------------------
       
   701 // RAnalyzeToolAllocator::AllocSize()
       
   702 // Gets the number of cells allocated on this heap, and 
       
   703 // the total space allocated to them.
       
   704 // -----------------------------------------------------------------------------
       
   705 //
       
   706 TInt RAnalyzeToolAllocator::AllocSize( TInt& aTotalAllocSize ) const
       
   707     {
       
   708     LOGSTR1( "ATMH RAnalyzeToolAllocator::AllocSize()" );
       
   709     
       
   710     // Acquire the mutex
       
   711     iMutex.Wait();
       
   712     
       
   713     // Acquire the memory information using original allocator
       
   714     TInt size = iAllocator->AllocSize( aTotalAllocSize );
       
   715     
       
   716     // Release the mutex
       
   717     iMutex.Signal();
       
   718     
       
   719     // Return the number of cells allocated on this heap.
       
   720     return size;
       
   721     }
       
   722 
       
   723 // -----------------------------------------------------------------------------
       
   724 // RAnalyzeToolAllocator::Available()
       
   725 // Gets the total free space currently available on the heap and the 
       
   726 // space available in the largest free block. The space available 
       
   727 // represents the total space which can be allocated. Note that 
       
   728 // compressing the heap may reduce the total free space available 
       
   729 // and the space available in the largest free block.
       
   730 // -----------------------------------------------------------------------------
       
   731 //
       
   732 TInt RAnalyzeToolAllocator::Available( TInt& aBiggestBlock ) const
       
   733     {
       
   734     LOGSTR1( "ATMH RAnalyzeToolAllocator::Available()" );
       
   735     
       
   736     // Acquire the mutex
       
   737     iMutex.Wait();
       
   738     
       
   739     // Acquire the memory information using original allocator
       
   740     TInt available = iAllocator->Available( aBiggestBlock );
       
   741     
       
   742     // Release the mutex
       
   743     iMutex.Signal();
       
   744     
       
   745     // Return the total free space currently available on the heap
       
   746     return available;
       
   747     }
       
   748 
       
   749 // -----------------------------------------------------------------------------
       
   750 // RAnalyzeToolAllocator::AllocLen()
       
   751 // Gets the length of the available space in the specified 
       
   752 // allocated cell.
       
   753 // -----------------------------------------------------------------------------
       
   754 //
       
   755 TInt RAnalyzeToolAllocator::AllocLen( const TAny* aCell ) const
       
   756     {
       
   757     LOGSTR1( "ATMH RAnalyzeToolAllocator::AllocLen()" ); 
       
   758     
       
   759     // Acquire the mutex
       
   760     iMutex.Wait();
       
   761     
       
   762     // Acquire the memory information using original allocator
       
   763     TInt len = iAllocator->AllocLen( aCell );
       
   764     
       
   765     // Release the mutex
       
   766     iMutex.Signal();
       
   767     
       
   768     // Return the length of the available space in the allocated cell.
       
   769     return len;
       
   770     }
       
   771 
       
   772 // -----------------------------------------------------------------------------
       
   773 // RAnalyzeToolAllocator::DebugFunction()
       
   774 // Invocates specified debug funtionality.
       
   775 // -----------------------------------------------------------------------------
       
   776 //
       
   777 TInt RAnalyzeToolAllocator::DebugFunction( TInt aFunc, TAny* a1, TAny* a2 )
       
   778     {
       
   779     LOGSTR2( "ATMH RAnalyzeToolAllocator::DebugFunction() %i", aFunc );
       
   780     
       
   781     // Acquire the mutex
       
   782     iMutex.Wait();
       
   783     
       
   784     // Invocate debug funtion using original allocator
       
   785     TInt debug = iAllocator->DebugFunction( aFunc, a1, a2 );
       
   786     
       
   787     switch( aFunc )
       
   788 		{  
       
   789 		case EMarkEnd:
       
   790 			{
       
   791 			// Disables the __UHEAP_MARKEND macro
       
   792 			LOGSTR1( "ATMH __UHEAP_MARKEND macro called" );
       
   793 			if ( debug > 0 )
       
   794 				{
       
   795 				LOGSTR2( "ATMH __UHEAP_MARKEND detects leaks: %d", debug );
       
   796 				// Because there is leaks the alloc panic will occur but
       
   797 				// lets return a zero to pretend that everything is OK
       
   798 				debug = 0;
       
   799 				}
       
   800 			}
       
   801 		break;
       
   802 		
       
   803 		default:
       
   804 			{
       
   805 			}
       
   806 		break;
       
   807 		}
       
   808     
       
   809     // Release the mutex
       
   810     iMutex.Signal();
       
   811     
       
   812     // Return information of the debug function success
       
   813     return debug;
       
   814     }
       
   815 
       
   816 // -----------------------------------------------------------------------------
       
   817 // RAnalyzeToolAllocator::Extension_()
       
   818 // Extension function
       
   819 // -----------------------------------------------------------------------------
       
   820 //
       
   821 TInt RAnalyzeToolAllocator::Extension_( TUint aExtensionId, TAny*& a0, 
       
   822     TAny* a1 ) 
       
   823     {
       
   824     LOGSTR1( "ATMH RAnalyzeToolAllocator::Extension_()" );
       
   825     
       
   826     // Acquire the mutex
       
   827     iMutex.Wait();
       
   828     
       
   829     // Invocate extension funtion using original allocator
       
   830     TInt ext = RAllocator::Extension_( aExtensionId, a0, a1 );
       
   831     
       
   832     // Release the mutex
       
   833     iMutex.Signal();
       
   834     
       
   835     // Return information of the extension function success
       
   836     return ext;
       
   837     }
       
   838 
       
   839 // -----------------------------------------------------------------------------
       
   840 // RAnalyzeToolAllocator::ShareHeap()
       
   841 // Share heap with other thread
       
   842 // -----------------------------------------------------------------------------
       
   843 //
       
   844 void RAnalyzeToolAllocator::ShareHeap()
       
   845     {
       
   846     LOGSTR1( "ATMH RAnalyzeToolAllocator::ShareHeap()" );
       
   847     
       
   848     // Call the overwrited Open function
       
   849     Open();
       
   850     }
       
   851     
       
   852 // -----------------------------------------------------------------------------
       
   853 // RAnalyzeToolAllocator::FindCurrentThreadStack()
       
   854 // Find the current thread which is using the heap
       
   855 // -----------------------------------------------------------------------------
       
   856 //
       
   857 TBool RAnalyzeToolAllocator::FindCurrentThreadStack( TUint32& aStackStart )
       
   858     {
       
   859     LOGSTR2( "ATMH RAnalyzeToolAllocator::FindCurrentThreadStack(), count( %i )", 
       
   860             iThreadArray.Count() );
       
   861     
       
   862     // Flag for indicating that right thread has been found
       
   863     TBool found( EFalse );
       
   864     // If threre is only one thread it must be the right thread
       
   865     if ( iThreadArray.Count() == KThreadCount )
       
   866         {
       
   867         if ( !iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
       
   868             {
       
   869             // This MUST BE the right thread
       
   870             //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
       
   871             }
       
   872         else if ( iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
       
   873             {
       
   874             found = ETrue;
       
   875             }
       
   876         }
       
   877     else
       
   878         {
       
   879         // Iterate through array to find right thread
       
   880         TInt count( iThreadArray.Count() );
       
   881         
       
   882         for ( TInt i = 0; i < count; i++ )
       
   883             {
       
   884             // Check if this is the right thread
       
   885             if ( iThreadArray[ i ].ThreadStackStart( aStackStart ) )
       
   886                 {
       
   887                 // Right thread found. Mark the flag
       
   888                 found = ETrue;
       
   889                 break;
       
   890                 }
       
   891             }
       
   892         // If right thread was not found the panic must be raised
       
   893         if ( !found )
       
   894             {
       
   895             //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
       
   896             }
       
   897         }
       
   898     return found;
       
   899     }
       
   900 
       
   901 // End of File