diff -r 185201be11b0 -r 516af714ebb4 perfsrv/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectThreadInfoObjects.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/perfsrv/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectThreadInfoObjects.cpp Fri Sep 17 08:38:31 2010 +0300 @@ -0,0 +1,3442 @@ +/* +* 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: +* +*/ + +#include + +// System includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// User includes +#include "MemSpyEngineOutputListItem.h" + +// Constants +const TInt KMemSpyNumericFormatBufferSize = 20; + +// Literal constants +_LIT( KMemSpyNumericHexFormat, "0x%08x" ); +_LIT( KMemSpyNumericDecFormat, "%d" ); +_LIT( KMemSpyNumericLongFormat, "%Ld" ); +_LIT( KMemSpyCaptionYes, "Yes" ); +_LIT( KMemSpyCaptionNo, "No" ); +_LIT( KMemSpyCaptionOn, "On" ); +_LIT( KMemSpyCaptionOff, "Off" ); +_LIT( KMemSpyUnavailable, "Unavailable" ); +_LIT( KMemSpyDead, "Dead" ); +_LIT( KMemSpyNoItems, "(No items)" ); + + + +CMemSpyThreadInfoItemBase::CMemSpyThreadInfoItemBase( CMemSpyThreadInfoContainer& aContainer, TMemSpyThreadInfoItemType aType, TBool aAsyncConstruction ) +: CMemSpyEngineObject( aContainer ), iContainer( aContainer ), iCallBack( CActive::EPriorityLow ), iType( aType ) + { + if ( aAsyncConstruction ) + { + TCallBack callBackMethod( CallConstructL, this ); + iCallBack.Set( callBackMethod ); + iCallBack.CallBack(); + } + } + + +CMemSpyThreadInfoItemBase::~CMemSpyThreadInfoItemBase() + { + TRAP_IGNORE( iContainer.NotifyObserverL( MMemSpyThreadInfoContainerObserver::EInfoItemDestroyed, iType ) ); + // + iItems.ResetAndDestroy(); + iItems.Close(); + } + + +TInt CMemSpyThreadInfoItemBase::CallConstructL( TAny* aSelf ) + { + CMemSpyThreadInfoItemBase* self = reinterpret_cast< CMemSpyThreadInfoItemBase* >( aSelf ); + self->iReady = EFalse; + + // Don't try to refresh dead thread + TInt err = KErrNone; + if ( !self->Container().Thread().IsDead() ) + { + TRAP(err, self->ConstructL()); + if ( err != KErrNone ) + { + #ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoItemBase::CallConstructL() - construction err: %d, iType: %d", err, self->iType ); + #endif + self->AddItemL( KMemSpyUnavailable, KNullDesC ); + self->iIsEmpty = ETrue; + } + else if ( self->MdcaCount() == 0 ) + { + self->AddItemL( KMemSpyNoItems, KNullDesC ); + self->iIsEmpty = ETrue; + } + } + else + { + self->AddItemL( KMemSpyDead, KNullDesC ); + self->iIsEmpty = ETrue; + } + // + self->iReady = ETrue; + return KErrNone; + } + + +EXPORT_C TInt CMemSpyThreadInfoItemBase::MdcaCount() const + { + return iItems.Count(); + } + + +EXPORT_C TPtrC CMemSpyThreadInfoItemBase::MdcaPoint( TInt aIndex ) const + { + CItem* item = iItems[ aIndex ]; + return TPtrC( item->Combined() ); + } + +EXPORT_C TPtrC CMemSpyThreadInfoItemBase::Caption(TInt aIndex ) const + { + CItem* item = iItems[ aIndex ]; + return TPtrC( item->Caption() ); + } + +EXPORT_C TPtrC CMemSpyThreadInfoItemBase::Value(TInt aIndex ) const + { + CItem* item = iItems[ aIndex ]; + return TPtrC( item->Value() ); + } + +EXPORT_C CMemSpyEngine& CMemSpyThreadInfoItemBase::Engine() const + { + return iContainer.Engine(); + } + + +EXPORT_C void CMemSpyThreadInfoItemBase::PrintL() + { + const TInt count = iItems.Count(); + if ( count > 0 && !iIsEmpty ) + { + CMemSpyEngine& engine = Engine(); + CMemSpyEngineOutputSink& sink = engine.Sink(); + + HBufC* name = MemSpyEngineUtils::CleanupTextLC( Name() ); + sink.OutputSectionHeadingL( *name, TChar('-') ); + CleanupStack::PopAndDestroy( name ); + sink.OutputPrefixSetLC( _L(" ") ); // Slight insertion + + // First pass to get max lengths + TInt maxLengthCaption = 0; + TInt maxLengthValue = 0; + + for( TInt j=0; jCaption().Length() ); + maxLengthValue = Max( maxLengthValue, item->Value().Length() ); + } + + // Second pass - real this time - to print the values + HBufC* line = HBufC::NewLC( ( maxLengthCaption + maxLengthValue ) + 20 ); + TPtr pLine( line->Des() ); + // + for( TInt i=0; iCaption() ); + + // Create value item & replace any further tabs + HBufC* value = MemSpyEngineUtils::CleanupTextLC( item->Value() ); + + // Now format the final line, with padding. + pLine.Justify( *caption, maxLengthCaption + 3, ELeft, TChar(' ') ); + pLine.Append( *value ); + CleanupStack::PopAndDestroy( 2, caption ); + + // Sink output + sink.OutputLineL( pLine ); + } + // + CleanupStack::PopAndDestroy( line ); + sink.OutputBlankLineL(); + CleanupStack::PopAndDestroy(); // clear prefix + } + } + + + +void CMemSpyThreadInfoItemBase::AddItemL( const TDesC& aCaption, const TDesC& aValue ) + { + CItem* item = CItem::NewLC( aCaption, aValue ); + iItems.AppendL( item ); + CleanupStack::Pop( item ); + } + + +void CMemSpyThreadInfoItemBase::AddItemHexL( const TDesC& aCaption, TUint aValue ) + { + TBuf val; + val.Format( KMemSpyNumericHexFormat, aValue ); + AddItemL( aCaption, val ); + } + + +void CMemSpyThreadInfoItemBase::AddItemDecimalL( const TDesC& aCaption, TInt aValue ) + { + TBuf val; + val.Format( KMemSpyNumericDecFormat, aValue ); + AddItemL( aCaption, val ); + } + + +void CMemSpyThreadInfoItemBase::AddItemLongL( const TDesC& aCaption, const TInt64& aValue ) + { + TBuf val; + val.Format( KMemSpyNumericLongFormat, aValue ); + AddItemL( aCaption, val ); + } + + +void CMemSpyThreadInfoItemBase::AddItemYesNoL( const TDesC& aCaption, TBool aYes ) + { + CItem* item = CItem::NewYesNoLC( aCaption, aYes ); + iItems.AppendL( item ); + CleanupStack::Pop( item ); + } + + +void CMemSpyThreadInfoItemBase::AddItemOnOffL( const TDesC& aCaption, TBool aOn ) + { + CItem* item = CItem::NewOnOffLC( aCaption, aOn ); + iItems.AppendL( item ); + CleanupStack::Pop( item ); + } + + +void CMemSpyThreadInfoItemBase::AddItemPercentageL( const TDesC& aCaption, TInt aOneHundredPercentValue, TInt aValue ) + { + const TMemSpyPercentText val( MemSpyEngineUtils::FormatPercentage( TReal( aOneHundredPercentValue ), TReal( aValue ) ) ); + AddItemL( aCaption, val ); + } + + +EXPORT_C void CMemSpyThreadInfoItemBase::RebuildL() + { + Reset(); + CallConstructL( this ); + } + + +EXPORT_C TBool CMemSpyThreadInfoItemBase::IsReady() const + { + return iReady; + } + + +EXPORT_C TMemSpyThreadInfoItemType CMemSpyThreadInfoItemBase::Type() const + { + return iType; + } + + +void CMemSpyThreadInfoItemBase::Reset() + { + iItems.ResetAndDestroy(); + } + + +void CMemSpyThreadInfoItemBase::StripProcessAndThreadNames( TDes& aText ) + { + StripProcessName( aText ); + StripThreadName( aText ); + } + + +void CMemSpyThreadInfoItemBase::StripProcessName( TDes& aText ) + { + CMemSpyProcess& process = Container().Thread().Process(); + const TPtrC processName( process.Name() ); + TFullName temp; + // + _LIT( KProcessNameUidFormat1, "%S.exe[%08x]" ); + temp.Format( KProcessNameUidFormat1, &processName, process.SID() ); + const TBool stripped = MemSpyEngineUtils::StripText( aText, temp ); + // + if ( stripped == EFalse ) + { + _LIT( KProcessNameUidFormat2, "%S[%08x]" ); + temp.Format( KProcessNameUidFormat2, &processName, process.SID() ); + MemSpyEngineUtils::StripText( aText, temp ); + } + } + + +void CMemSpyThreadInfoItemBase::StripThreadName( TDes& aText ) + { + CMemSpyThread& thread = Container().Thread(); + const TPtrC threadName( thread.Name() ); + const TBool stripped = MemSpyEngineUtils::StripText( aText, threadName ); + (void) stripped; + } + + +CMemSpyThreadInfoItemBase::CItem& CMemSpyThreadInfoItemBase::Item( TInt aIndex ) + { + CItem* item = iItems[ aIndex ]; + return *item; + } + + +const CMemSpyThreadInfoItemBase::CItem& CMemSpyThreadInfoItemBase::Item( TInt aIndex ) const + { + const CItem* item = iItems[ aIndex ]; + return *item; + } + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoItemBase::CItem::CItem() + { + } + + +CMemSpyThreadInfoItemBase::CItem::~CItem() + { + delete iCaption; + delete iValue; + delete iCombined; + } + + +void CMemSpyThreadInfoItemBase::CItem::ConstructL( const TDesC& aCaption, const TDesC& aValue ) + { + iCaption = aCaption.AllocL(); + iValue = aValue.AllocL(); + // + UpdateCombinedL(); + } + + +CMemSpyThreadInfoItemBase::CItem* CMemSpyThreadInfoItemBase::CItem::NewLC( const CItem& aCopyMe ) + { + CItem* self = new(ELeave) CItem(); + CleanupStack::PushL( self ); + self->ConstructL( aCopyMe.Caption(), aCopyMe.Value() ); + return self; + } + + +CMemSpyThreadInfoItemBase::CItem* CMemSpyThreadInfoItemBase::CItem::NewLC( const TDesC& aCaption ) + { + CItem* self = new(ELeave) CItem(); + CleanupStack::PushL( self ); + self->ConstructL( aCaption, KNullDesC ); + return self; + } + + +CMemSpyThreadInfoItemBase::CItem* CMemSpyThreadInfoItemBase::CItem::NewLC( const TDesC& aCaption, const TDesC& aValue ) + { + CItem* self = new(ELeave) CItem(); + CleanupStack::PushL( self ); + self->ConstructL( aCaption, aValue ); + return self; + } + + +CMemSpyThreadInfoItemBase::CItem* CMemSpyThreadInfoItemBase::CItem::NewHexLC( const TDesC& aCaption, TUint aValue ) + { + CItem* ret = CItem::NewLC( aCaption ); + ret->SetHexL( aValue ); + return ret; + } + + +CMemSpyThreadInfoItemBase::CItem* CMemSpyThreadInfoItemBase::CItem::NewDecimalLC( const TDesC& aCaption, TInt aValue ) + { + CItem* ret = CItem::NewLC( aCaption ); + ret->SetDecimalL( aValue ); + return ret; + } + + +CMemSpyThreadInfoItemBase::CItem* CMemSpyThreadInfoItemBase::CItem::NewLongLC( const TDesC& aCaption, const TInt64& aValue ) + { + CItem* ret = CItem::NewLC( aCaption ); + ret->SetLongL( aValue ); + return ret; + } + + +CMemSpyThreadInfoItemBase::CItem* CMemSpyThreadInfoItemBase::CItem::NewYesNoLC( const TDesC& aCaption, TBool aYes ) + { + CItem* ret = CItem::NewLC( aCaption ); + ret->SetYesNoL( aYes ); + return ret; + } + + +CMemSpyThreadInfoItemBase::CItem* CMemSpyThreadInfoItemBase::CItem::NewOnOffLC( const TDesC& aCaption, TBool aOn ) + { + CItem* ret = CItem::NewLC( aCaption ); + ret->SetOnOffL( aOn ); + return ret; + } + + +CMemSpyThreadInfoItemBase::CItem* CMemSpyThreadInfoItemBase::CItem::NewPercentageLC( const TDesC& aCaption, TInt aOneHundredPercentValue, TInt aValue ) + { + CItem* ret = CItem::NewLC( aCaption ); + ret->SetPercentageL( aOneHundredPercentValue, aValue ); + return ret; + } + + +void CMemSpyThreadInfoItemBase::CItem::SetValueL( const TDesC& aValue ) + { + if ( iValue == NULL ) + { + iValue = aValue.AllocL(); + } + else + { + if ( iValue->Des().MaxLength() < aValue.Length() ) + { + iValue = iValue->ReAllocL( aValue.Length() ); + } + + // Now its safe to assign new content + *iValue = aValue; + } + + UpdateCombinedL(); + } + + +void CMemSpyThreadInfoItemBase::CItem::SetHexL( TUint aValue ) + { + TBuf val; + val.Format( KMemSpyNumericHexFormat, aValue ); + SetValueL( val ); + } + + +void CMemSpyThreadInfoItemBase::CItem::SetDecimalL( TInt aValue ) + { + TBuf val; + val.Format( KMemSpyNumericDecFormat, aValue ); + SetValueL( val ); + } + + +void CMemSpyThreadInfoItemBase::CItem::SetLongL( const TInt64& aValue ) + { + TBuf val; + val.Format( KMemSpyNumericLongFormat, aValue ); + SetValueL( val ); + } + + +void CMemSpyThreadInfoItemBase::CItem::SetYesNoL( TBool aYes ) + { + if ( aYes ) + { + SetValueL( KMemSpyCaptionYes ); + } + else + { + SetValueL( KMemSpyCaptionNo ); + } + } + + +void CMemSpyThreadInfoItemBase::CItem::SetOnOffL( TBool aOn ) + { + if ( aOn ) + { + SetValueL( KMemSpyCaptionOn ); + } + else + { + SetValueL( KMemSpyCaptionOff ); + } + } + + +void CMemSpyThreadInfoItemBase::CItem::SetPercentageL( TInt aOneHundredPercentValue, TInt aValue ) + { + const TMemSpyPercentText val( MemSpyEngineUtils::FormatPercentage( TReal( aOneHundredPercentValue ), TReal( aValue ) ) ); + SetValueL( val ); + } + + +void CMemSpyThreadInfoItemBase::CItem::UpdateCombinedL() + { + const TInt requiredLength = Caption().Length() + Value().Length() + 10; + // + if ( iCombined == NULL ) + { + iCombined = HBufC::NewL( requiredLength ); + } + else if ( iCombined->Des().MaxLength() < requiredLength ) + { + iCombined = iCombined->ReAllocL( requiredLength ); + } + + TPtr pCombined( iCombined->Des() ); + pCombined.Zero(); + pCombined.Append( _L("\t") ); + pCombined.Append( Caption() ); + pCombined.Append( _L("\t\t") ); + pCombined.Append( Value() ); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoGeneral::CMemSpyThreadInfoGeneral( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoItemBase( aContainer, EMemSpyThreadInfoItemTypeGeneralInfo, aAsyncConstruction ) + { + } + + +void CMemSpyThreadInfoGeneral::ConstructL() + { + TBuf<50> temp; + RThread thread; + Container().Thread().OpenLC( thread ); + const CMemSpyProcess& process = Container().Thread().Process(); + + _LIT( KItem1, "Thread Id" ); + AddItemLongL( KItem1, thread.Id() ); + + _LIT( KItem1a, "Process Id" ); + AddItemLongL( KItem1a, (TUint) process.Id() ); + + _LIT( KItem1b, "SID" ); + AddItemHexL( KItem1b, process.SID() ); + + _LIT( KItem1c, "VID" ); + AddItemHexL( KItem1c, process.VID() ); + + _LIT( KItem2, "Thread Priority" ); + CMemSpyThread::AppendPriority( temp, thread.Priority() ); + AddItemL( KItem2, temp ); + temp.Zero(); + + _LIT( KItem3, "Process Priority" ); + CMemSpyProcess::AppendPriority( temp, thread.ProcessPriority() ); + AddItemL( KItem3, temp ); + temp.Zero(); + + _LIT( KItem4, "Request Count" ); + AddItemDecimalL( KItem4, thread.RequestCount() ); + + TInt processHandleCount = 0; + TInt threadHandleCount = 0; + thread.HandleCount( processHandleCount, threadHandleCount ); + + _LIT( KItem5a, "Process Handles" ); + AddItemDecimalL( KItem5a, processHandleCount ); + + _LIT( KItem5b, "Thread Handles" ); + AddItemDecimalL( KItem5b, threadHandleCount ); + + // Thread handle info + THandleInfo handleInfo; + thread.HandleInfo( &handleInfo ); + + _LIT( KItem5c, "Num. Proc. (Using)" ); + AddItemDecimalL( KItem5c, handleInfo.iNumProcesses ); + + _LIT( KItem5d, "Num. Thread (Using)" ); + AddItemDecimalL( KItem5d, handleInfo.iNumThreads ); + + _LIT( KItem5e, "Attributes" ); + AddItemDecimalL( KItem5e, thread.Attributes() ); + + // CPU time (request special kernel build) + TTimeIntervalMicroSeconds cpuTime; + if ( thread.GetCpuTime( cpuTime ) == KErrNone ) + { + _LIT( KItem5f, "CPU Time (us)" ); + const TInt64 time = cpuTime.Int64(); + AddItemLongL( KItem5f, time ); + } + + // Exit info + _LIT( KItem6, "Exit Type" ); + CMemSpyThread::AppendExitType( temp, thread.ExitType() ); + AddItemL( KItem6, temp ); + temp.Zero(); + + if ( thread.ExitType() != EExitPending ) + { + _LIT( KItem7, "Exit Reason" ); + AddItemDecimalL( KItem7, thread.ExitReason() ); + + _LIT( KItem8, "Exit Category" ); + const TExitCategoryName cat( thread.ExitCategory() ); + AddItemL( KItem8, cat ); + } + + // Registers + MakeRegisterListingL( thread ); + + CleanupStack::PopAndDestroy( &thread ); + + Container().NotifyObserverL( MMemSpyThreadInfoContainerObserver::EInfoItemChanged, Type() ); + } + + +CMemSpyThreadInfoGeneral* CMemSpyThreadInfoGeneral::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoGeneral* self = new(ELeave) CMemSpyThreadInfoGeneral( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoGeneral::Name() const + { + _LIT(KName, "\tGeneral"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoGeneral::MakeRegisterListingL( RThread& aThread ) + { +#ifndef __WINS__ + _LIT(KRegFormatGeneral, "R%02d"); + _LIT(KRegFormatSP, "SP"); + _LIT(KRegFormatLR, "LR"); + _LIT(KRegFormatPC, "PC"); + _LIT(KRegFormatFlags, "Flags"); + _LIT(KRegFormatDACR, "DACR"); // Data access control register + // + TArmRegSet regList; + TPckg pRegList( regList ); + // + aThread.Context( pRegList ); + TArmReg* pReg = reinterpret_cast( ®List ); + // + for( TInt i=0; i buf; + buf.Format( KRegFormatGeneral, i ); + AddItemHexL( buf, regValue ); + } + else + { + TPtrC pCaption( KRegFormatGeneral ); + // + if ( i == EArmSp ) + { + pCaption.Set( KRegFormatSP ); + } + else if ( i == EArmLr ) + { + pCaption.Set( KRegFormatLR ); + } + else if ( i == EArmPc ) + { + pCaption.Set( KRegFormatPC ); + } + else if ( i == EArmFlags ) + { + pCaption.Set( KRegFormatFlags ); + } + else if ( i == EArmDacr ) + { + pCaption.Set( KRegFormatDACR ); + } + // + AddItemHexL( pCaption, regValue ); + } + } +#else + (void) aThread; +#endif + } + + + + + + + + + + + + + + +CMemSpyThreadInfoHeap::CMemSpyThreadInfoHeap( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoItemBase( aContainer, EMemSpyThreadInfoItemTypeHeap, aAsyncConstruction ) + { + } + + +void CMemSpyThreadInfoHeap::ConstructL() + { + CMemSpyEngineHelperHeap& heapHelper = Engine().HelperHeap(); + + // Get heap info first of all + TMemSpyHeapInfo info; + heapHelper.GetHeapInfoUserL( Container().Thread().Process().Id(), Container().Thread().Id(), info ); + CMemSpyEngineOutputList* list = heapHelper.NewHeapSummaryShortLC( info ); + + // Now add each item to our view + const TInt count = list->Count(); + for( TInt i=0; iItem( i ); + // + AddItemL( item.Caption(), item.Value() ); + } + + // Tidy up + CleanupStack::PopAndDestroy( list ); + Container().NotifyObserverL( MMemSpyThreadInfoContainerObserver::EInfoItemChanged, Type() ); + } + + +CMemSpyThreadInfoHeap* CMemSpyThreadInfoHeap::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoHeap* self = new(ELeave) CMemSpyThreadInfoHeap( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoHeap::Name() const + { + _LIT(KName, "\tHeap"); + return TPtrC( KName ); + } + + + + + + + + + + + + + + + + +CMemSpyThreadInfoActiveObjects::CMemSpyThreadInfoActiveObjects( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoItemBase( aContainer, EMemSpyThreadInfoItemTypeActiveObject, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoActiveObjects::~CMemSpyThreadInfoActiveObjects() + { + delete iItems; + } + + +void CMemSpyThreadInfoActiveObjects::ConstructL() + { + CMemSpyEngine& engine = Container().Thread().Process().Engine(); + engine.ProcessSuspendLC( Container().Thread().Process().Id() ); + // + CMemSpyEngineActiveObjectArray* activeObjects = engine.HelperActiveObject().ActiveObjectListL( Container().Thread() ); + delete iItems; + iItems = activeObjects; + // + CleanupStack::PopAndDestroy(); // ProcessSuspendLC + + Container().NotifyObserverL( MMemSpyThreadInfoContainerObserver::EInfoItemChanged, Type() ); + } + + +CMemSpyThreadInfoActiveObjects* CMemSpyThreadInfoActiveObjects::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoActiveObjects* self = new(ELeave) CMemSpyThreadInfoActiveObjects( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoActiveObjects::Name() const + { + _LIT(KName, "\tActive Objects"); + return TPtrC( KName ); + } + + +EXPORT_C TInt CMemSpyThreadInfoActiveObjects::MdcaCount() const + { + TInt count = 0; + // + if ( iItems ) + { + count = iItems->MdcaCount(); + } + // + return count; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoActiveObjects::MdcaPoint(TInt aIndex) const + { + TPtrC ret( KNullDesC ); + // + if ( iItems ) + { + ret.Set( iItems->MdcaPoint( aIndex ) ); + } + // + return ret; + } + + + + + + + + + + + + +CMemSpyThreadInfoOpenFiles::CMemSpyThreadInfoOpenFiles( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoItemBase( aContainer, EMemSpyThreadInfoItemTypeOpenFiles, aAsyncConstruction ) + { + } + + +void CMemSpyThreadInfoOpenFiles::ConstructL() + { + _LIT(KSpace, " "); + // + const TThreadId myThreadId = Container().Thread().Id(); + CMemSpyEngine& engine = Container().Thread().Process().Engine(); + RFs& fsSession = engine.FsSession(); + // + TMemSpySizeText valueBuf; + TBuf<128> timeBuf; + TOpenFileScan scanner( fsSession ); + // + CFileList* list = NULL; + scanner.NextL( list ); + + while( list != NULL ) + { + if ( scanner.ThreadId() == myThreadId ) + { + CleanupStack::PushL( list ); + + const TInt entryCount = list->Count(); + for(TInt i=0; iConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoOpenFiles::Name() const + { + _LIT(KName, "\tOpen Files"); + return TPtrC( KName ); + } + + + + + + + + + + + + + + + + +CMemSpyThreadInfoStack::CMemSpyThreadInfoStack( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoItemBase( aContainer, EMemSpyThreadInfoItemTypeStack, aAsyncConstruction ) + { + } + + +void CMemSpyThreadInfoStack::ConstructL() + { + CMemSpyEngine& engine = Container().Thread().Process().Engine(); + engine.ProcessSuspendLC( Container().Thread().Process().Id() ); + // + TMemSpyDriverStackInfo info; + const TInt error = engine.Driver().GetStackInfo( Container().Thread().Id(), info ); + User::LeaveIfError( error ); + + _LIT( KItem1, "Size" ); + AddItemDecimalL( KItem1, info.iUserStackSize ); + +#ifndef __WINS__ + const TInt userStackUsage = (TInt) ( info.iUserStackBase + info.iUserStackSize ) - info.iUserStackPointer; + const TInt userStackHighWaterMarkUsage = (TInt) ( info.iUserStackBase + info.iUserStackSize ) - info.iUserStackHighWatermark; + + _LIT( KItem2, "Stack used" ); + AddItemDecimalL( KItem2, userStackUsage ); + + _LIT( KItem3, "(percentage)" ); + AddItemPercentageL( KItem3, info.iUserStackSize, userStackUsage ); + + _LIT( KItem4, "High watermark" ); + AddItemDecimalL( KItem4, userStackHighWaterMarkUsage ); + + _LIT( KItem5, "(percentage)" ); + AddItemPercentageL( KItem5, info.iUserStackSize, userStackHighWaterMarkUsage ); +#endif + + _LIT( KItem6, "Base address" ); + AddItemHexL( KItem6, info.iUserStackBase ); + +#ifndef __WINS__ + _LIT( KItem7, "Current pointer" ); + AddItemHexL( KItem7, info.iUserStackPointer ); +#endif + // + CleanupStack::PopAndDestroy(); // ProcessSuspendLC + + Container().NotifyObserverL( MMemSpyThreadInfoContainerObserver::EInfoItemChanged, Type() ); + } + + +CMemSpyThreadInfoStack* CMemSpyThreadInfoStack::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoStack* self = new(ELeave) CMemSpyThreadInfoStack( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoStack::Name() const + { + _LIT(KName, "\tStack"); + return TPtrC( KName ); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoChunk::CMemSpyThreadInfoChunk( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoItemBase( aContainer, EMemSpyThreadInfoItemTypeChunk, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoChunk::~CMemSpyThreadInfoChunk() + { + delete iList; + } + + +void CMemSpyThreadInfoChunk::ConstructL() + { + CMemSpyEngine& engine = Container().Thread().Process().Engine(); + engine.ProcessSuspendLC( Container().Thread().Process().Id() ); + // + CMemSpyEngineChunkList* list = engine.HelperChunk().ListForThreadL( Container().Thread().Id() ); + delete iList; + iList = list; + // + CleanupStack::PopAndDestroy(); // ProcessSuspendLC + + Container().NotifyObserverL( MMemSpyThreadInfoContainerObserver::EInfoItemChanged, Type() ); + } + + +CMemSpyThreadInfoChunk* CMemSpyThreadInfoChunk::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoChunk* self = new(ELeave) CMemSpyThreadInfoChunk( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoChunk::Name() const + { + _LIT(KName, "\tChunks"); + return TPtrC( KName ); + } + + +EXPORT_C TInt CMemSpyThreadInfoChunk::MdcaCount() const + { + TInt count = 0; + // + if ( iList ) + { + count = iList->MdcaCount(); + } + // + return count; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoChunk::MdcaPoint(TInt aIndex) const + { + TPtrC ret( KNullDesC ); + // + if ( iList ) + { + ret.Set( iList->MdcaPoint( aIndex ) ); + } + // + return ret; + } + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoCodeSeg::CMemSpyThreadInfoCodeSeg( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoItemBase( aContainer, EMemSpyThreadInfoItemTypeCodeSeg, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoCodeSeg::~CMemSpyThreadInfoCodeSeg() + { + delete iList; + } + + +void CMemSpyThreadInfoCodeSeg::ConstructL() + { + CMemSpyEngine& engine = Container().Thread().Process().Engine(); + engine.ProcessSuspendLC( Container().Thread().Process().Id() ); + // + CMemSpyEngineCodeSegList* list = engine.HelperCodeSegment().CodeSegmentListL( Container().Thread().Process().Id() ); + delete iList; + iList = list; + // + CleanupStack::PopAndDestroy(); // ProcessSuspendLC + + Container().NotifyObserverL( MMemSpyThreadInfoContainerObserver::EInfoItemChanged, Type() ); + } + + +CMemSpyThreadInfoCodeSeg* CMemSpyThreadInfoCodeSeg::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoCodeSeg* self = new(ELeave) CMemSpyThreadInfoCodeSeg( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoCodeSeg::Name() const + { + _LIT(KName, "\tCode Segments"); + return TPtrC( KName ); + } + + +EXPORT_C TInt CMemSpyThreadInfoCodeSeg::MdcaCount() const + { + TInt count = 0; + // + if ( iList ) + { + count = iList->MdcaCount(); + } + // + return count; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoCodeSeg::MdcaPoint(TInt aIndex) const + { + TPtrC ret( KNullDesC ); + // + if ( iList ) + { + ret.Set( iList->MdcaPoint( aIndex ) ); + } + // + return ret; + } + + + + + + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoHandleObjectBase::CMemSpyThreadInfoHandleObjectBase( CMemSpyThreadInfoContainer& aContainer, TMemSpyThreadInfoItemType aItemType, TMemSpyDriverContainerType aContainerType, TBool aAsyncConstruction ) +: CMemSpyThreadInfoItemBase( aContainer, aItemType, aAsyncConstruction ), iContainerType( aContainerType ) + { + } + + +CMemSpyThreadInfoHandleObjectBase::~CMemSpyThreadInfoHandleObjectBase() + { +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoHandleObjectBase::~CMemSpyThreadInfoHandleObjectBase() - this: 0x%08x", this ); +#endif + iInfoItems.Close(); + } + + +void CMemSpyThreadInfoHandleObjectBase::ConstructL() + { +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoHandleObjectBase::ConstructL() - START" ); +#endif + iInfoItems.Reset(); + // + CMemSpyProcess& process = Container().Thread().Process(); + CMemSpyEngine& engine = process.Engine(); + engine.ProcessSuspendLC( process.Id() ); + // + RArray handles; + CleanupClosePushL( handles ); + GetHandlesL( handles ); +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoHandleObjectBase::ConstructL() - got %d handle entries...", handles.Count() ); +#endif + // + TFullName name; + TMemSpyDriverHandleInfoGeneric info; + // + const TInt count = handles.Count(); + for (TInt i=0; i& aArray ) + { +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoHandleByContainer::GetHandlesL() - START - container: %d", ContainerType() ); +#endif + + aArray.Reset(); + + // Our handles will be stored here... duplicates are filtered out + TInt r = KErrNone; + TInt c = KMemSpyDefaultMaxHandleCount; + TAny* handles[ KMemSpyDefaultMaxHandleCount ]; + + CMemSpyProcess& process = Container().Thread().Process(); + CMemSpyEngine& engine = process.Engine(); + TIdentityRelation finder( THandleWrapper::Match ); + + // First get the handles for the process + if ( r == KErrNone ) + { + c = KMemSpyDefaultMaxHandleCount; + r = engine.Driver().GetProcessHandlesByType( process.Id(), ContainerType(), handles, c ); + if ( r == KErrNone && c > 0 ) + { + c = Min( c, KMemSpyDefaultMaxHandleCount ); + for( TInt i=0; i= 0 ) + { + // Increment reference count for duplicates... + CMemSpyThreadInfoHandleObjectBase::THandleWrapper& existingEntry = aArray[ errorOrIndex ]; + ++existingEntry.iRefCount; +#ifdef _DEBUG + RDebug::Printf( " dupe entry - count is now: %d", existingEntry.iRefCount ); +#endif + } + } + } + } + + // Next get the handles for the thread + if ( r == KErrNone ) + { + c = KMemSpyDefaultMaxHandleCount; + r = engine.Driver().GetThreadHandlesByType( Container().Thread().Id(), ContainerType(), handles, c ); + if ( r == KErrNone && c > 0 ) + { + c = Min( c, KMemSpyDefaultMaxHandleCount ); + for( TInt i=0; i= 0 ) + { + // Increment reference count for duplicates... + CMemSpyThreadInfoHandleObjectBase::THandleWrapper& existingEntry = aArray[ errorOrIndex ]; + ++existingEntry.iRefCount; +#ifdef _DEBUG + RDebug::Printf( " dupe entry - count is now: %d", existingEntry.iRefCount ); +#endif + } + } + } + } + +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoHandleByContainer::GetHandlesL() - final handle listing: " ); + + const TInt finalCount = aArray.Count(); + for( TInt i=0; iConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoServer::Name() const + { + _LIT(KName, "\tServers Running in Thread"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoServer::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& /*aItem*/, TInt /*aRefCount*/, TDes& aFullName ) + { + AddItemL( aFullName, KNullDesC ); + } + + +EXPORT_C TPtrC CMemSpyThreadInfoServer::SessionType( TIpcSessionType aType ) + { + _LIT( KUnsharable, "Unsharable" ); + _LIT( KSharable, "Sharable" ); + _LIT( KGlobalSharable, "Global Sharable" ); + // + TPtrC pType(KNullDesC); + switch( aType ) + { + case EIpcSession_Unsharable: + pType.Set( KUnsharable ); + break; + case EIpcSession_Sharable: + pType.Set( KSharable ); + break; + case EIpcSession_GlobalSharable: + pType.Set( KGlobalSharable ); + break; + default: + pType.Set( KMemSpyUnavailable ); + break; + } + // + return pType; + } + + + + + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoSession::CMemSpyThreadInfoSession( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoHandleByContainer( aContainer, EMemSpyThreadInfoItemTypeSession, EMemSpyDriverContainerTypeSession, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoSession::~CMemSpyThreadInfoSession() + { + iServerNames.ResetAndDestroy(); + iServerNames.Close(); + } + + +CMemSpyThreadInfoSession* CMemSpyThreadInfoSession::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoSession* self = new(ELeave) CMemSpyThreadInfoSession( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoSession::Name() const + { + _LIT(KName, "\tClient <-> Server\nConnections"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoSession::Reset() + { + CMemSpyThreadInfoHandleByContainer::Reset(); + iServerNames.ResetAndDestroy(); + } + + +EXPORT_C TInt CMemSpyThreadInfoSession::ConnectionCount( const TDesC& aName ) const + { + TInt ret = 0; + +#ifdef _DEBUG + RDebug::Print( _L("CMemSpyThreadInfoSession::ConnectionCount() - START - aName: %S"), &aName ); +#endif + + // See if we have an entry with that name... + TInt foundIndex = 0; + TRAP(ret, foundIndex = FindServerL(aName)); + + if (ret == KErrNone) + { + // If we did, get the count + if ( foundIndex >=0 && foundIndex < iServerNames.Count() ) + { + ret = iServerNames[ foundIndex ]->iCount; + } + } + +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoSession::ConnectionCount() - END - ret: %d", ret ); +#endif + // + return ret; + } + +TInt CMemSpyThreadInfoSession::FindServerL( const TDesC& aName ) const + { + TIdentityRelation comparer( CompareEntries ); + HBufC* name = aName.AllocLC(); + CSessionInfoEntry* entry = new(ELeave) CSessionInfoEntry( name ); + CleanupStack::Pop( name ); // don't destroy it as name is now owned by entry + CleanupStack::PushL( entry ); + const TInt foundIndex = iServerNames.Find( entry, comparer ); + User::LeaveIfError(foundIndex); // so we only return a real index + CleanupStack::PopAndDestroy( entry ); + return foundIndex; + } + +void CMemSpyThreadInfoSession::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& aItem, TInt /*aRefCount*/, TDes& aFullName ) + { + // Check whether we have the item already + TIdentityRelation comparer( CompareEntries ); + + // Prepare object, just in case we don't find it... + HBufC* name = aFullName.AllocLC(); + +#ifdef _DEBUG + TBuf origName; origName.Copy( aItem.iName ); + RDebug::Print( _L("CMemSpyThreadInfoSession::HandleContainerItemL() - START - handle: 0x%08x, type: %d, origName: %S, modName: %S"), aItem.iHandle, aItem.iType, &origName, name ); +#else + (void) aItem; +#endif + + CSessionInfoEntry* entry = new(ELeave) CSessionInfoEntry( name ); + CleanupStack::Pop( name ); + CleanupStack::PushL( entry ); + + // Search + const TInt foundIndex = iServerNames.Find( entry, comparer ); + if ( foundIndex == KErrNotFound ) + { + // Make new entry + iServerNames.AppendL( entry ); + CleanupStack::Pop( entry ); + } + else if ( foundIndex >= 0 ) + { + // Existing entry, increment count + CleanupStack::PopAndDestroy( entry ); + entry = iServerNames[ foundIndex ]; + ++entry->iCount; + } + else + { + CleanupStack::PopAndDestroy( entry ); + } + +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoSession::HandleContainerItemL() - END - foundIndex: %d", foundIndex ); +#endif + } + + +void CMemSpyThreadInfoSession::HandleAllItemsLocatedL() + { + _LIT(KSecondLineFormatStringCount1, "1 connection"); + _LIT(KSecondLineFormatStringCountMoreThanOne, "%d connections"); + TBuf<50> buf; + + // All items have been found, now create listbox entries + const TInt count = iServerNames.Count(); + for( TInt i=0; iiCount == 1 ) + { + buf.Copy( KSecondLineFormatStringCount1 ); + } + else + { + buf.Format( KSecondLineFormatStringCountMoreThanOne, entry->iCount ); + } + + AddItemL( *entry->iName, buf ); + } + } + + +TBool CMemSpyThreadInfoSession::CompareEntries( const CSessionInfoEntry& aLeft, const CSessionInfoEntry& aRight ) + { + return ( aLeft.iName->CompareF( *aRight.iName ) == 0 ); + } + + + + + + + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoSemaphore::CMemSpyThreadInfoSemaphore( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoHandleByContainer( aContainer, EMemSpyThreadInfoItemTypeSemaphore, EMemSpyDriverContainerTypeSemaphore, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoSemaphore* CMemSpyThreadInfoSemaphore::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoSemaphore* self = new(ELeave) CMemSpyThreadInfoSemaphore( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoSemaphore::Name() const + { + _LIT(KName, "\tSemaphores"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoSemaphore::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& aItem, TInt /*aRefCount*/, TDes& aFullName ) + { + _LIT( KFormatSpec, "Count: %d" ); + TBuf<50> buf; + buf.AppendFormat( KFormatSpec, aItem.iCount ); + + AddItemL( aFullName, buf ); + } + + + + + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoMutex::CMemSpyThreadInfoMutex( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoHandleByContainer( aContainer, EMemSpyThreadInfoItemTypeMutex, EMemSpyDriverContainerTypeMutex, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoMutex* CMemSpyThreadInfoMutex::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoMutex* self = new(ELeave) CMemSpyThreadInfoMutex( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoMutex::Name() const + { + _LIT(KName, "\tMutexes"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoMutex::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& aItem, TInt /*aRefCount*/, TDes& aFullName ) + { + _LIT( KFormatSpec, "Count: %d" ); + TBuf<50> buf; + buf.AppendFormat( KFormatSpec, aItem.iCount ); + + AddItemL( aFullName, buf ); + } + + + + + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoTimer::CMemSpyThreadInfoTimer( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoHandleByContainer( aContainer, EMemSpyThreadInfoItemTypeTimer, EMemSpyDriverContainerTypeTimer, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoTimer* CMemSpyThreadInfoTimer::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoTimer* self = new(ELeave) CMemSpyThreadInfoTimer( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoTimer::Name() const + { + _LIT(KName, "\tTimers"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoTimer::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& aItem, TInt /*aRefCount*/, TDes& /*aFullName*/ ) + { + // Get useful strings + TBuf<20> state; + GetTimerState( aItem.iTimerState, state ); + TBuf<20> type; + GetTimerType( aItem.iTimerType, type ); + + AddItemL( type, state ); + } + + +void CMemSpyThreadInfoTimer::GetTimerState( TMemSpyDriverTimerState aState, TDes& aBuf ) + { + switch( aState ) + { + default: + case EMemSpyDriverTimerStateUnknown: + { + _LIT(KStateUnknown, "Unknown"); + aBuf.Copy( KStateUnknown ); + } + break; + case EMemSpyDriverTimerStateIdle: + { + _LIT(KStateIdle, "Idle"); + aBuf.Copy( KStateIdle ); + } + break; + case EMemSpyDriverTimerStateWaiting: + { + _LIT(KStateWaiting, "Waiting"); + aBuf.Copy( KStateWaiting ); + } + break; + case EMemSpyDriverTimerStateWaitHighRes: + { + _LIT(KStateWaitHighRes, "Waiting, High Res."); + aBuf.Copy( KStateWaitHighRes ); + } + break; + } + } + + +void CMemSpyThreadInfoTimer::GetTimerType( TMemSpyDriverTimerType aType, TDes& aBuf ) + { + switch( aType ) + { + case EMemSpyDriverTimerTypeRelative: + { + _LIT( KType, "Relative" ); + aBuf.Copy( KType ); + } + break; + case EMemSpyDriverTimerTypeAbsolute: + { + _LIT( KType, "Absolute" ); + aBuf.Copy( KType ); + } + break; + case EMemSpyDriverTimerTypeHighRes: + { + _LIT( KType, "High Res." ); + aBuf.Copy( KType ); + } + break; + case EMemSpyDriverTimerTypeInactivity: + { + _LIT( KType, "Inactivity" ); + aBuf.Copy( KType ); + } + break; + default: + { + _LIT( KType, "Unknown" ); + aBuf.Copy( KType ); + } + break; + } + } + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoLDD::CMemSpyThreadInfoLDD( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoHandleByContainer( aContainer, EMemSpyThreadInfoItemTypeLDD, EMemSpyDriverContainerTypeLogicalDevice, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoLDD* CMemSpyThreadInfoLDD::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoLDD* self = new(ELeave) CMemSpyThreadInfoLDD( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoLDD::Name() const + { + _LIT(KName, "\tLogical Device Drivers"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoLDD::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& aItem, TInt /*aRefCount*/, TDes& aFullName ) + { + _LIT( KFormatSpec, "Open channels: %d" ); + TBuf<50> buf; + buf.AppendFormat( KFormatSpec, aItem.iOpenChannels ); + + AddItemL( aFullName, buf ); + } + + + + + + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoPDD::CMemSpyThreadInfoPDD( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoHandleByContainer( aContainer, EMemSpyThreadInfoItemTypePDD, EMemSpyDriverContainerTypePhysicalDevice, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoPDD* CMemSpyThreadInfoPDD::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoPDD* self = new(ELeave) CMemSpyThreadInfoPDD( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoPDD::Name() const + { + _LIT(KName, "\tPhysical Device Drivers"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoPDD::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& /*aItem*/, TInt /*aRefCount*/, TDes& aFullName ) + { + AddItemL( aFullName, KNullDesC ); + } + + + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoLogicalChannel::CMemSpyThreadInfoLogicalChannel( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoHandleByContainer( aContainer, EMemSpyThreadInfoItemTypeLogicalChannel, EMemSpyDriverContainerTypeLogicalChannel, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoLogicalChannel* CMemSpyThreadInfoLogicalChannel::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoLogicalChannel* self = new(ELeave) CMemSpyThreadInfoLogicalChannel( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoLogicalChannel::Name() const + { + _LIT(KName, "\tLogical DD Channels"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoLogicalChannel::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& /*aItem*/, TInt /*aRefCount*/, TDes& aFullName ) + { + AddItemL( aFullName, KNullDesC ); + } + + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoChangeNotifier::CMemSpyThreadInfoChangeNotifier( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoHandleByContainer( aContainer, EMemSpyThreadInfoItemTypeChangeNotifier, EMemSpyDriverContainerTypeChangeNotifier, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoChangeNotifier* CMemSpyThreadInfoChangeNotifier::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoChangeNotifier* self = new(ELeave) CMemSpyThreadInfoChangeNotifier( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoChangeNotifier::Name() const + { + _LIT(KName, "\tChange Notifiers"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoChangeNotifier::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& /*aItem*/, TInt /*aRefCount*/, TDes& aFullName ) + { + AddItemL( aFullName, KNullDesC ); + } + + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoUndertaker::CMemSpyThreadInfoUndertaker( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoHandleByContainer( aContainer, EMemSpyThreadInfoItemTypeUndertaker, EMemSpyDriverContainerTypeUndertaker, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoUndertaker* CMemSpyThreadInfoUndertaker::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoUndertaker* self = new(ELeave) CMemSpyThreadInfoUndertaker( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoUndertaker::Name() const + { + _LIT(KName, "\tUndertakers"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoUndertaker::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& /*aItem*/, TInt /*aRefCount*/, TDes& aFullName ) + { + AddItemL( aFullName, KNullDesC ); + } + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoOwnedThreadHandles::CMemSpyThreadInfoOwnedThreadHandles( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoHandleByContainer( aContainer, EMemSpyThreadInfoItemTypeOwnedThreadHandles, EMemSpyDriverContainerTypeThread, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoOwnedThreadHandles* CMemSpyThreadInfoOwnedThreadHandles::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoOwnedThreadHandles* self = new(ELeave) CMemSpyThreadInfoOwnedThreadHandles( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoOwnedThreadHandles::Name() const + { + _LIT(KName, "\tHandles to other\nThreads"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoOwnedThreadHandles::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& aItem, TInt aRefCount, TDes& aFullName ) + { + const TInt bracketPosStart = aFullName.LocateF( TChar('[') ); + const TInt doubleColonPos = aFullName.FindF( _L("::" ) ); + // + if ( bracketPosStart >= 0 && doubleColonPos > bracketPosStart && doubleColonPos < aFullName.Length() - 2 ) + { + // Process + TPtrC pProcessName( aFullName.Left( bracketPosStart ) ); + HBufC* caption = HBufC::NewLC( KMaxName + 10 ); + TPtr pCaption( caption->Des() ); + pCaption.AppendFormat( _L("[%2d] %S"), aRefCount, &pProcessName ); + + // Thread id & thread name + TPtrC pThreadName( aFullName.Mid( doubleColonPos + 2 ) ); + HBufC* value = HBufC::NewLC( KMaxName + 10 ); + TPtr pValue( value->Des() ); + pValue.AppendFormat( _L("[%3d] %S"), aItem.iId, &pThreadName ); + + // Add it & tidy up + AddItemL( pCaption, pValue ); + CleanupStack::PopAndDestroy( 2, caption ); + } + else + { + AddItemL( aFullName, KNullDesC ); + } + } + + + + + + + + + +CMemSpyThreadInfoOwnedProcessHandles::CMemSpyThreadInfoOwnedProcessHandles( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoHandleByContainer( aContainer, EMemSpyThreadInfoItemTypeOwnedProcessHandles, EMemSpyDriverContainerTypeProcess, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoOwnedProcessHandles* CMemSpyThreadInfoOwnedProcessHandles::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoOwnedProcessHandles* self = new(ELeave) CMemSpyThreadInfoOwnedProcessHandles( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoOwnedProcessHandles::Name() const + { + _LIT(KName, "\tHandles to other\nProcesses"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoOwnedProcessHandles::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& aItem, TInt aRefCount, TDes& aFullName ) + { + const TInt bracketPosStart = aFullName.LocateF( TChar('[') ); + const TInt doubleColonPos = aFullName.FindF( _L("::" ) ); + // + if ( bracketPosStart >= 0 && doubleColonPos > bracketPosStart && doubleColonPos < aFullName.Length() - 2 ) + { + // Process + TPtrC pProcessName( aFullName.Left( bracketPosStart ) ); + HBufC* caption = HBufC::NewLC( KMaxName + 10 ); + TPtr pCaption( caption->Des() ); + pCaption.AppendFormat( _L("[%2d] %S"), aRefCount, &pProcessName ); + + // Thread id & thread name + TPtrC pThreadName( aFullName.Mid( doubleColonPos + 2 ) ); + HBufC* value = HBufC::NewLC( KMaxName + 10 ); + TPtr pValue( value->Des() ); + pValue.AppendFormat( _L("[%3d] %S"), aItem.iId, &pThreadName ); + + // Add it & tidy up + AddItemL( pCaption, pValue ); + CleanupStack::PopAndDestroy( 2, caption ); + } + else + { + AddItemL( aFullName, KNullDesC ); + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoReferencedBy::CMemSpyThreadInfoReferencedBy( CMemSpyThreadInfoContainer& aContainer, TMemSpyThreadInfoItemType aItemType, TMemSpyDriverContainerType aContainerType, TBool aAsyncConstruction ) +: CMemSpyThreadInfoHandleObjectBase( aContainer, aItemType, aContainerType, aAsyncConstruction ) + { + } + + +void CMemSpyThreadInfoReferencedBy::GetHandlesL( RArray& aArray ) + { + aArray.Reset(); + // + TInt r = KErrNone; + // + CMemSpyProcess& process = Container().Thread().Process(); + CMemSpyEngine& engine = process.Engine(); + TIdentityRelation finder( THandleWrapper::Match ); + + // We need to either search through: + // + // a) all thread & process handles looking for *this thread*, or + // b) all thread & process handles looking for *this process* + // + // We abuse the "container type" as a means of deciding whether it is + // the thread or the process we are looking for. + // + RMemSpyDriverClient& driver = engine.Driver(); + if ( ContainerType() == EMemSpyDriverContainerTypeProcess ) + { + const TUint id = Container().Thread().Process().Id(); + r = driver.GetReferencesToMyProcess( id ); + } + else if ( ContainerType() == EMemSpyDriverContainerTypeThread ) + { + const TUint id = Container().Thread().Id(); + r = driver.GetReferencesToMyThread( id ); + } + else + { + ASSERT( EFalse ); + } + User::LeaveIfError( r ); + + RMemSpyMemStreamReader stream = driver.StreamOpenL(); + CleanupClosePushL( stream ); + + // Extract thread matches + const TInt threadCount = stream.ReadInt32L(); + for( TInt i=0; i= 0 ) + { + // Increment reference count for duplicates... + CMemSpyThreadInfoHandleObjectBase::THandleWrapper& existingEntry = aArray[ errorOrIndex ]; + ++existingEntry.iRefCount; + } + } + + // Extract process matches + const TInt processCount = stream.ReadInt32L(); + for( TInt i=0; i= 0 ) + { + // Increment reference count for duplicates... + CMemSpyThreadInfoHandleObjectBase::THandleWrapper& existingEntry = aArray[ errorOrIndex ]; + ++existingEntry.iRefCount; + } + } + + // Tidy up + CleanupStack::PopAndDestroy( &stream ); + } + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoOtherThreads::CMemSpyThreadInfoOtherThreads( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoReferencedBy( aContainer, EMemSpyThreadInfoItemTypeOtherThreads, EMemSpyDriverContainerTypeThread, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoOtherThreads* CMemSpyThreadInfoOtherThreads::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoOtherThreads* self = new(ELeave) CMemSpyThreadInfoOtherThreads( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoOtherThreads::Name() const + { + _LIT(KName, "\tReferences this Thread"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoOtherThreads::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& /*aItem*/, TInt /*aRefCount*/, TDes& aFullName ) + { + AddItemL( aFullName, KNullDesC ); + } + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoOtherProcesses::CMemSpyThreadInfoOtherProcesses( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoReferencedBy( aContainer, EMemSpyThreadInfoItemTypeOtherProcesses, EMemSpyDriverContainerTypeProcess, aAsyncConstruction ) + { + } + + +CMemSpyThreadInfoOtherProcesses* CMemSpyThreadInfoOtherProcesses::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoOtherProcesses* self = new(ELeave) CMemSpyThreadInfoOtherProcesses( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoOtherProcesses::Name() const + { + _LIT(KName, "\tReferences this Process"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoOtherProcesses::HandleContainerItemL( TMemSpyDriverHandleInfoGeneric& /*aItem*/, TInt /*aRefCount*/, TDes& aFullName ) + { + AddItemL( aFullName, KNullDesC ); + } + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoMemoryTracking::CMemSpyThreadInfoMemoryTracking( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoItemBase( aContainer, EMemSpyThreadInfoItemTypeMemoryTracking, aAsyncConstruction ), iTotalIncludesSharedMemory( ETrue ) + { + } + + +CMemSpyThreadInfoMemoryTracking::~CMemSpyThreadInfoMemoryTracking() + { +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoMemoryTracking::~CMemSpyThreadInfoMemoryTracking() - START - this: 0x%08x, iTracker: 0x%08x", this, iTracker ); +#endif + // + TrackingObserverRemove( *this ); + // + delete iInfoHWM; + delete iInfoPeak; + delete iInfoCurrent; + // +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoMemoryTracking::~CMemSpyThreadInfoMemoryTracking() - END - this: 0x%08x, iTracker: 0x%08x", this, iTracker ); +#endif + } + + +void CMemSpyThreadInfoMemoryTracking::ConstructL() + { +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoMemoryTracking::ConstructL() - START - this: 0x%08x, iTracker: 0x%08x", this, iTracker ); +#endif + CMemSpyEngine& engine = Container().Thread().Process().Engine(); + // + const TProcessId pid = Container().Thread().Process().Id(); + iTracker = engine.HelperProcess().TrackerOrNull( pid ); + +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoMemoryTracking::ConstructL() - requesting observer add... - this: 0x%08x, iTracker: 0x%08x", this, iTracker ); +#endif + TrackingObserverAddL( *this ); + // +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoMemoryTracking::ConstructL() - preparing info item... - this: 0x%08x, iTracker: 0x%08x", this, iTracker ); +#endif + if ( iTracker ) + { + delete iInfoCurrent; + iInfoCurrent = NULL; + iInfoCurrent = CMemSpyThreadInfoMemoryTrackingStatisticsCurrent::NewLC( Container(), EFalse ); + CleanupStack::Pop( iInfoCurrent ); + // + delete iInfoHWM; + iInfoHWM = NULL; + iInfoHWM = CMemSpyThreadInfoMemoryTrackingStatisticsHWM::NewLC( Container(), EFalse ); + CleanupStack::Pop( iInfoHWM ); + // + delete iInfoPeak; + iInfoPeak = NULL; + iInfoPeak = CMemSpyThreadInfoMemoryTrackingStatisticsPeak::NewLC( Container(), EFalse ); + CleanupStack::Pop( iInfoPeak ); + } + +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoMemoryTracking::ConstructL() - prepared info items - this: 0x%08x, iTracker: 0x%08x", this, iTracker ); +#endif + + // Prepare items + _LIT( KItem0, "Tracking" ); + AddItemOnOffL( KItem0, ( iTracker ) ? iTracker->AmTracking() : EFalse ); + + TInt64 valCurrent( 0 ); + if ( iTracker ) + { + if ( TotalIncludesSharedMemory() ) + { + valCurrent = iTracker->InfoCurrent().TotalIncShared(); + } + else + { + valCurrent = iTracker->InfoCurrent().TotalExcShared(); + } + } + _LIT( KItem1, "Total [Current]" ); + AddItemLongL( KItem1, valCurrent ); + + TInt64 valHWM( 0 ); + if ( iTracker ) + { + if ( TotalIncludesSharedMemory() ) + { + valHWM = iTracker->InfoHWMIncShared().TotalIncShared(); + } + else + { + valHWM = iTracker->InfoHWMExcShared().TotalExcShared(); + } + } + _LIT( KItem2, "Total [HWM]" ); + AddItemLongL( KItem2, valHWM ); + + TInt64 valPeak( 0 ); + if ( iTracker ) + { + if ( TotalIncludesSharedMemory() ) + { + valPeak = iTracker->InfoPeaks().TotalIncShared(); + } + else + { + valPeak = iTracker->InfoPeaks().TotalExcShared(); + } + } + _LIT( KItem3, "Total [Peaks]" ); + AddItemLongL( KItem3, valPeak ); + + // + Container().NotifyObserverL( MMemSpyThreadInfoContainerObserver::EInfoItemChanged, Type() ); +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoMemoryTracking::ConstructL() - END - this: 0x%08x", this ); +#endif + } + + +CMemSpyThreadInfoMemoryTracking* CMemSpyThreadInfoMemoryTracking::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoMemoryTracking* self = new(ELeave) CMemSpyThreadInfoMemoryTracking( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +EXPORT_C TPtrC CMemSpyThreadInfoMemoryTracking::Name() const + { + _LIT(KName, "\tMemory Tracking"); + return TPtrC( KName ); + } + + +EXPORT_C TBool CMemSpyThreadInfoMemoryTracking::TrackingActive() const + { + return ( iTracker != NULL ? iTracker->AmTracking() : EFalse ); + } + + +EXPORT_C TBool CMemSpyThreadInfoMemoryTracking::TotalIncludesSharedMemory() const + { + return iTotalIncludesSharedMemory; + } + + +EXPORT_C void CMemSpyThreadInfoMemoryTracking::TrackingSetTotalIncludesSharedMemoryL( TBool aIncludesSharedMemory ) + { + iTotalIncludesSharedMemory = aIncludesSharedMemory; + + if ( iTracker ) + { + iInfoCurrent->SetTotalIncludesSharedMemoryL( aIncludesSharedMemory ); + iInfoHWM->SetTotalIncludesSharedMemoryL( aIncludesSharedMemory ); + iInfoPeak->SetTotalIncludesSharedMemoryL( aIncludesSharedMemory ); + + // Update totals + TRAP_IGNORE( UpdateCaptionsL( iTracker->InfoCurrent(), iTracker->InfoHWMIncShared(), iTracker->InfoHWMExcShared() ) ); + } + } + + +EXPORT_C void CMemSpyThreadInfoMemoryTracking::TrackingStartL() + { + if ( iTracker == NULL ) + { + CMemSpyProcess& process = Container().Thread().Process(); + CMemSpyEngine& engine = process.Engine(); + iTracker = &engine.HelperProcess().TrackerL( process ); + + // Make sure we are also listening to the tracker! + TrackingObserverAddL( *this ); + // + CMemSpyThreadInfoMemoryTrackingStatisticsCurrent* infoCurrent = CMemSpyThreadInfoMemoryTrackingStatisticsCurrent::NewLC( Container(), EFalse ); + CMemSpyThreadInfoMemoryTrackingStatisticsHWM* infoHWM = CMemSpyThreadInfoMemoryTrackingStatisticsHWM::NewLC( Container(), EFalse ); + CMemSpyThreadInfoMemoryTrackingStatisticsPeak* infoPeak = CMemSpyThreadInfoMemoryTrackingStatisticsPeak::NewLC( Container(), EFalse ); + // + iInfoCurrent = infoCurrent; + iInfoHWM = infoHWM; + iInfoPeak = infoPeak; + // + CleanupStack::Pop( iInfoPeak ); + CleanupStack::Pop( infoHWM ); + CleanupStack::Pop( infoCurrent ); + // + TrackingSetTotalIncludesSharedMemoryL( iTotalIncludesSharedMemory ); + } + + iTracker->StartL(); + + UpdateCaptionsL(); + } + + +EXPORT_C void CMemSpyThreadInfoMemoryTracking::TrackingStopL() + { + if ( iTracker != NULL ) + { + iTracker->Stop(); + } + + UpdateCaptionsL(); + } + + +EXPORT_C void CMemSpyThreadInfoMemoryTracking::TrackingResetHWML() + { + if ( iTracker != NULL ) + { + iTracker->ResetHWML(); + } + } + + +EXPORT_C void CMemSpyThreadInfoMemoryTracking::TrackingObserverAddL( MMemSpyEngineProcessMemoryTrackerObserver& aObserver ) + { +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoMemoryTracking::TrackingObserverAddL() - START - iTracker: 0x%08x, this: 0x%08x", iTracker, this ); +#endif + + if ( iTracker != NULL ) + { + iTracker->AddObserverL( aObserver ); + } + +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoMemoryTracking::TrackingObserverAddL() - END - iTracker: 0x%08x, this: 0x%08x", iTracker, this ); +#endif + } + + +EXPORT_C void CMemSpyThreadInfoMemoryTracking::TrackingObserverRemove( MMemSpyEngineProcessMemoryTrackerObserver& aObserver ) + { +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoMemoryTracking::TrackingObserverRemove() - START - iTracker: 0x%08x, this: 0x%08x", iTracker, this ); +#endif + + if ( iTracker != NULL ) + { + iTracker->RemoveObserver( aObserver ); + } + +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoMemoryTracking::TrackingObserverRemove() - END - iTracker: 0x%08x, this: 0x%08x", iTracker, this ); +#endif + } + + +EXPORT_C MDesCArray& CMemSpyThreadInfoMemoryTracking::InfoCurrent() + { + return *iInfoCurrent; + } + + +EXPORT_C MDesCArray& CMemSpyThreadInfoMemoryTracking::InfoHWM() + { + return *iInfoHWM; + } + + +EXPORT_C MDesCArray& CMemSpyThreadInfoMemoryTracking::InfoPeak() + { + return *iInfoPeak; + } + + +void CMemSpyThreadInfoMemoryTracking::HandleMemoryTrackingStartedL() + { + __ASSERT_ALWAYS( iTracker, MemSpyEngineUtils::Panic( EMemSpyEnginePanicTrackerNull1 ) ); + CMemSpyThreadInfoItemBase::CItem& trackingItem = Item( 0 ); + trackingItem.SetOnOffL( iTracker->AmTracking() ); + // + Container().NotifyObserverL( MMemSpyThreadInfoContainerObserver::EInfoItemChanged, Type() ); + } + + +void CMemSpyThreadInfoMemoryTracking::HandleMemoryTrackingStoppedL() + { + __ASSERT_ALWAYS( iTracker, MemSpyEngineUtils::Panic( EMemSpyEnginePanicTrackerNull2 ) ); + CMemSpyThreadInfoItemBase::CItem& trackingItem = Item( 0 ); + trackingItem.SetOnOffL( iTracker->AmTracking() ); + // + Container().NotifyObserverL( MMemSpyThreadInfoContainerObserver::EInfoItemChanged, Type() ); + } + + +void CMemSpyThreadInfoMemoryTracking::HandleMemoryChangedL( const TProcessId& /*aPid*/, const TMemSpyDriverProcessInspectionInfo& aInfoCurrent, const TMemSpyDriverProcessInspectionInfo& aHWMInfoIncShared, const TMemSpyDriverProcessInspectionInfo& aHWMInfoExcShared ) + { +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoMemoryTracking::HandleMemoryChangedL() - START - this: 0x%08x", this ); +#endif + + __ASSERT_ALWAYS( iTracker, MemSpyEngineUtils::Panic( EMemSpyEnginePanicTrackerNull3 ) ); + UpdateCaptionsL( aInfoCurrent, aHWMInfoIncShared, aHWMInfoExcShared ); + +#ifdef _DEBUG + RDebug::Printf( "CMemSpyThreadInfoMemoryTracking::HandleMemoryChangedL() - END - this: 0x%08x", this ); +#endif + } + + +void CMemSpyThreadInfoMemoryTracking::UpdateCaptionsL() + { + if ( iTracker ) + { + UpdateCaptionsL( iTracker->InfoCurrent(), iTracker->InfoHWMIncShared(), iTracker->InfoHWMExcShared() ); + } + } + + +void CMemSpyThreadInfoMemoryTracking::UpdateCaptionsL( const TMemSpyDriverProcessInspectionInfo& aInfoCurrent, const TMemSpyDriverProcessInspectionInfo& aHWMInfoIncShared, const TMemSpyDriverProcessInspectionInfo& aHWMInfoExcShared ) + { + if ( iTracker ) + { + // Update caption + Item( 0 ).SetOnOffL( TrackingActive() ); + + if ( TotalIncludesSharedMemory() ) + { + Item( 1 ).SetLongL( aInfoCurrent.TotalIncShared() ); + Item( 2 ).SetLongL( aHWMInfoIncShared.TotalIncShared() ); + Item( 3 ).SetLongL( iTracker->InfoPeaks().TotalIncShared() ); + } + else + { + Item( 1 ).SetLongL( aInfoCurrent.TotalExcShared() ); + Item( 2 ).SetLongL( aHWMInfoExcShared.TotalExcShared() ); + Item( 3 ).SetLongL( iTracker->InfoPeaks().TotalExcShared() ); + } + + Container().NotifyObserverL( MMemSpyThreadInfoContainerObserver::EInfoItemChanged, Type() ); + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoMemoryTrackingStatisticsCurrent::CMemSpyThreadInfoMemoryTrackingStatisticsCurrent( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoItemBase( aContainer, EMemSpyThreadInfoItemTypeMemoryTrackingCurrent, aAsyncConstruction ), iTotalIncludesSharedMemory( ETrue ) + { + } + + +CMemSpyThreadInfoMemoryTrackingStatisticsCurrent::~CMemSpyThreadInfoMemoryTrackingStatisticsCurrent() + { + if ( iTracker ) + { + iTracker->RemoveObserver( *this ); + } + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsCurrent::ConstructL() + { + CMemSpyEngine& engine = Container().Thread().Process().Engine(); + // + if ( iTracker ) + { + iTracker->RemoveObserver( *this ); + } + iTracker = &Container().Engine().HelperProcess().TrackerL( Container().Thread().Process() ); + if ( iTracker ) + { + iTracker->AddObserverL( *this ); + // + _LIT( KItem1, "Stack Memory" ); + AddItemDecimalL( KItem1, iTracker->InfoCurrent().iMemoryStack ); + // + _LIT( KItem2, "Heap Memory" ); + AddItemDecimalL( KItem2, iTracker->InfoCurrent().iMemoryHeap ); + // + _LIT( KItem3, "Local Chunk Memory" ); + AddItemDecimalL( KItem3, iTracker->InfoCurrent().iMemoryChunkLocal ); + // + _LIT( KItem4, "Shared Chunk Memory" ); + AddItemDecimalL( KItem4, iTracker->InfoCurrent().iMemoryChunkShared ); + // + _LIT( KItem5, "Global Data Memory" ); + AddItemDecimalL( KItem5, iTracker->InfoCurrent().iMemoryGlobalData ); + // + _LIT( KItem6, "Total" ); + if ( iTotalIncludesSharedMemory ) + { + AddItemLongL( KItem6, iTracker->InfoCurrent().TotalIncShared() ); + } + else + { + AddItemLongL( KItem6, iTracker->InfoCurrent().TotalExcShared() ); + } + } + } + + +CMemSpyThreadInfoMemoryTrackingStatisticsCurrent* CMemSpyThreadInfoMemoryTrackingStatisticsCurrent::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoMemoryTrackingStatisticsCurrent* self = new(ELeave) CMemSpyThreadInfoMemoryTrackingStatisticsCurrent( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +TPtrC CMemSpyThreadInfoMemoryTrackingStatisticsCurrent::Name() const + { + _LIT(KName, "\tCurrent Statistics"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsCurrent::SetTotalIncludesSharedMemoryL( TBool aIncludesSharedMemory ) + { + iTotalIncludesSharedMemory = aIncludesSharedMemory; + + // Update totals + HandleMemoryChangedL( iTracker->ProcessId(), iTracker->InfoCurrent(), iTracker->InfoHWMIncShared(), iTracker->InfoHWMExcShared() ); + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsCurrent::HandleMemoryTrackingStartedL() + { + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsCurrent::HandleMemoryTrackingStoppedL() + { + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsCurrent::HandleMemoryChangedL( const TProcessId& /*aPid*/, const TMemSpyDriverProcessInspectionInfo& aInfoCurrent, const TMemSpyDriverProcessInspectionInfo& /*aHWMInfoIncShared*/, const TMemSpyDriverProcessInspectionInfo& /*aHWMInfoExcShared*/ ) + { + Item( 0 ).SetDecimalL( aInfoCurrent.iMemoryStack ); + Item( 1 ).SetDecimalL( aInfoCurrent.iMemoryHeap ); + Item( 2 ).SetDecimalL( aInfoCurrent.iMemoryChunkLocal ); + Item( 3 ).SetDecimalL( aInfoCurrent.iMemoryChunkShared ); + Item( 4 ).SetDecimalL( aInfoCurrent.iMemoryGlobalData ); + // + if ( iTotalIncludesSharedMemory ) + { + Item( 5 ).SetLongL( aInfoCurrent.TotalIncShared() ); + } + else + { + Item( 5 ).SetLongL( aInfoCurrent.TotalExcShared() ); + } + } + + + + + + + + + + + + + + + + + + + +CMemSpyThreadInfoMemoryTrackingStatisticsPeak::CMemSpyThreadInfoMemoryTrackingStatisticsPeak( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoItemBase( aContainer, EMemSpyThreadInfoItemTypeMemoryTrackingPeak, aAsyncConstruction ), iTotalIncludesSharedMemory( ETrue ) + { + } + + +CMemSpyThreadInfoMemoryTrackingStatisticsPeak::~CMemSpyThreadInfoMemoryTrackingStatisticsPeak() + { + if ( iTracker ) + { + iTracker->RemoveObserver( *this ); + } + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsPeak::ConstructL() + { + CMemSpyEngine& engine = Container().Thread().Process().Engine(); + // + if ( iTracker ) + { + iTracker->RemoveObserver( *this ); + } + iTracker = &Container().Engine().HelperProcess().TrackerL( Container().Thread().Process() ); + if ( iTracker ) + { + iTracker->AddObserverL( *this ); + // + _LIT( KItem1, "Stack Memory" ); + AddItemDecimalL( KItem1, iTracker->InfoPeaks().iMemoryStack ); + // + _LIT( KItem2, "Heap Memory" ); + AddItemDecimalL( KItem2, iTracker->InfoPeaks().iMemoryHeap ); + // + _LIT( KItem3, "Local Chunk Memory" ); + AddItemDecimalL( KItem3, iTracker->InfoPeaks().iMemoryChunkLocal ); + // + _LIT( KItem4, "Shared Chunk Memory" ); + AddItemDecimalL( KItem4, iTracker->InfoPeaks().iMemoryChunkShared ); + // + _LIT( KItem5, "Global Data Memory" ); + AddItemDecimalL( KItem5, iTracker->InfoPeaks().iMemoryGlobalData ); + // + _LIT( KItem6, "Total" ); + if ( iTotalIncludesSharedMemory ) + { + AddItemLongL( KItem6, iTracker->InfoPeaks().TotalIncShared() ); + } + else + { + AddItemLongL( KItem6, iTracker->InfoPeaks().TotalExcShared() ); + } + } + } + + +CMemSpyThreadInfoMemoryTrackingStatisticsPeak* CMemSpyThreadInfoMemoryTrackingStatisticsPeak::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoMemoryTrackingStatisticsPeak* self = new(ELeave) CMemSpyThreadInfoMemoryTrackingStatisticsPeak( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +TPtrC CMemSpyThreadInfoMemoryTrackingStatisticsPeak::Name() const + { + _LIT(KName, "\tPeak Statistics"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsPeak::SetTotalIncludesSharedMemoryL( TBool aIncludesSharedMemory ) + { + iTotalIncludesSharedMemory = aIncludesSharedMemory; + + // Update totals + HandleMemoryChangedL( iTracker->ProcessId(), iTracker->InfoCurrent(), iTracker->InfoHWMIncShared(), iTracker->InfoHWMExcShared() ); + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsPeak::HandleMemoryTrackingStartedL() + { + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsPeak::HandleMemoryTrackingStoppedL() + { + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsPeak::HandleMemoryChangedL( const TProcessId& /*aPid*/, const TMemSpyDriverProcessInspectionInfo& /*aInfoCurrent*/, const TMemSpyDriverProcessInspectionInfo& /*aHWMInfoIncShared*/, const TMemSpyDriverProcessInspectionInfo& /*aHWMInfoExcShared*/ ) + { + Item( 0 ).SetDecimalL( iTracker->InfoPeaks().iMemoryStack ); + Item( 1 ).SetDecimalL( iTracker->InfoPeaks().iMemoryHeap ); + Item( 2 ).SetDecimalL( iTracker->InfoPeaks().iMemoryChunkLocal ); + Item( 3 ).SetDecimalL( iTracker->InfoPeaks().iMemoryChunkShared ); + Item( 4 ).SetDecimalL( iTracker->InfoPeaks().iMemoryGlobalData ); + // + if ( iTotalIncludesSharedMemory ) + { + Item( 5 ).SetLongL( iTracker->InfoPeaks().TotalIncShared() ); + } + else + { + Item( 5 ).SetLongL( iTracker->InfoPeaks().TotalExcShared() ); + } + } + + + + + + + + + + + + + + + + +CMemSpyThreadInfoMemoryTrackingStatisticsHWM::CMemSpyThreadInfoMemoryTrackingStatisticsHWM( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) +: CMemSpyThreadInfoItemBase( aContainer, EMemSpyThreadInfoItemTypeMemoryTrackingHWM, aAsyncConstruction ), iTotalIncludesSharedMemory( ETrue ) + { + } + + +CMemSpyThreadInfoMemoryTrackingStatisticsHWM::~CMemSpyThreadInfoMemoryTrackingStatisticsHWM() + { + if ( iTracker ) + { + iTracker->RemoveObserver( *this ); + } + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsHWM::ConstructL() + { + CMemSpyEngine& engine = Container().Thread().Process().Engine(); + // + if ( iTracker ) + { + iTracker->RemoveObserver( *this ); + } + iTracker = &Container().Engine().HelperProcess().TrackerL( Container().Thread().Process() ); + if ( iTracker ) + { + iTracker->AddObserverL( *this ); + // + _LIT( KItem1, "Stack Memory" ); + _LIT( KItem2, "Heap Memory" ); + _LIT( KItem3, "Local Chunk Memory" ); + _LIT( KItem4, "Shared Chunk Memory" ); + _LIT( KItem5, "Global Data Memory" ); + _LIT( KItem6, "Total" ); + // + if ( iTotalIncludesSharedMemory ) + { + AddItemDecimalL( KItem1, iTracker->InfoHWMIncShared().iMemoryStack ); + AddItemDecimalL( KItem2, iTracker->InfoHWMIncShared().iMemoryHeap ); + AddItemDecimalL( KItem3, iTracker->InfoHWMIncShared().iMemoryChunkLocal ); + AddItemDecimalL( KItem4, iTracker->InfoHWMIncShared().iMemoryChunkShared ); + AddItemDecimalL( KItem5, iTracker->InfoHWMIncShared().iMemoryGlobalData ); + AddItemLongL( KItem6, iTracker->InfoHWMIncShared().TotalIncShared() ); + } + else + { + AddItemDecimalL( KItem1, iTracker->InfoHWMExcShared().iMemoryStack ); + AddItemDecimalL( KItem2, iTracker->InfoHWMExcShared().iMemoryHeap ); + AddItemDecimalL( KItem3, iTracker->InfoHWMExcShared().iMemoryChunkLocal ); + AddItemDecimalL( KItem4, iTracker->InfoHWMExcShared().iMemoryChunkShared ); + AddItemDecimalL( KItem5, iTracker->InfoHWMExcShared().iMemoryGlobalData ); + AddItemLongL( KItem6, iTracker->InfoHWMExcShared().TotalExcShared() ); + } + } + } + + +CMemSpyThreadInfoMemoryTrackingStatisticsHWM* CMemSpyThreadInfoMemoryTrackingStatisticsHWM::NewLC( CMemSpyThreadInfoContainer& aContainer, TBool aAsyncConstruction ) + { + CMemSpyThreadInfoMemoryTrackingStatisticsHWM* self = new(ELeave) CMemSpyThreadInfoMemoryTrackingStatisticsHWM( aContainer, aAsyncConstruction ); + CleanupStack::PushL( self ); + if ( !aAsyncConstruction ) + { + self->ConstructL(); + } + return self; + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsHWM::SetTotalIncludesSharedMemoryL( TBool aIncludesSharedMemory ) + { + iTotalIncludesSharedMemory = aIncludesSharedMemory; + + // Update totals + HandleMemoryChangedL( iTracker->ProcessId(), iTracker->InfoCurrent(), iTracker->InfoHWMIncShared(), iTracker->InfoHWMExcShared() ); + } + + +TPtrC CMemSpyThreadInfoMemoryTrackingStatisticsHWM::Name() const + { + _LIT(KName, "\tHigh-Water-Mark Statistics"); + return TPtrC( KName ); + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsHWM::HandleMemoryTrackingStartedL() + { + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsHWM::HandleMemoryTrackingStoppedL() + { + } + + +void CMemSpyThreadInfoMemoryTrackingStatisticsHWM::HandleMemoryChangedL( const TProcessId& /*aPid*/, const TMemSpyDriverProcessInspectionInfo& /*aInfoCurrent*/, const TMemSpyDriverProcessInspectionInfo& aHWMInfoIncShared, const TMemSpyDriverProcessInspectionInfo& aHWMInfoExcShared ) + { + if ( iTotalIncludesSharedMemory ) + { + Item( 0 ).SetDecimalL( aHWMInfoIncShared.iMemoryStack ); + Item( 1 ).SetDecimalL( aHWMInfoIncShared.iMemoryHeap ); + Item( 2 ).SetDecimalL( aHWMInfoIncShared.iMemoryChunkLocal ); + Item( 3 ).SetDecimalL( aHWMInfoIncShared.iMemoryChunkShared ); + Item( 4 ).SetDecimalL( aHWMInfoIncShared.iMemoryGlobalData ); + Item( 5 ).SetLongL( aHWMInfoIncShared.TotalIncShared() ); + } + else + { + Item( 0 ).SetDecimalL( aHWMInfoExcShared.iMemoryStack ); + Item( 1 ).SetDecimalL( aHWMInfoExcShared.iMemoryHeap ); + Item( 2 ).SetDecimalL( aHWMInfoExcShared.iMemoryChunkLocal ); + Item( 3 ).SetDecimalL( aHWMInfoExcShared.iMemoryChunkShared ); + Item( 4 ).SetDecimalL( aHWMInfoExcShared.iMemoryGlobalData ); + Item( 5 ).SetLongL( aHWMInfoExcShared.TotalExcShared() ); + } + }