libraries/ltkutils/tsrc/tallochelper.cpp
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // tallochelper.cpp
       
     2 // 
       
     3 // Copyright (c) 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "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 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #include <fshell/ioutils.h>
       
    14 #include <fshell/common.mmh>
       
    15 #include <fshell/heaputils.h>
       
    16 #include <fshell/ltkutils.h>
       
    17 
       
    18 using namespace IoUtils;
       
    19 using LtkUtils::RAllocatorHelper;
       
    20 
       
    21 class CCmdTAllocHelper : public CCommandBase
       
    22 	{
       
    23 public:
       
    24 	static CCommandBase* NewLC();
       
    25 	~CCmdTAllocHelper();
       
    26 private:
       
    27 	CCmdTAllocHelper();
       
    28 	void PrintStats(const TDesC& aDesc);
       
    29 
       
    30 	void AllocL(TInt aSize, TInt aNumber=1);
       
    31 	void Free(TInt aNumber=1);
       
    32 	void FormatSize(TDes& aBuf, TInt64 aSize);
       
    33 	static TBool WalkCallback(RAllocatorHelper& aAlloc, TAny* aContext, RAllocatorHelper::TExtendedCellType aType, TLinAddr aAddress, TInt aLength);
       
    34 	static void RHeapWalkCallback(TAny* aContext, RHeap::TCellType aType, TAny* aCell, TInt aLength);
       
    35 
       
    36 private: // From CCommandBase.
       
    37 	virtual const TDesC& Name() const;
       
    38 	virtual const TDesC& Description() const;
       
    39 	virtual void DoRunL();
       
    40 	virtual void ArgumentsL(RCommandArgumentList& aArguments);
       
    41 	virtual void OptionsL(RCommandOptionList& aOptions);
       
    42 private:
       
    43 	RAllocatorHelper iAlloc;
       
    44 	RArray<TAny*> iAllocations;
       
    45 	TBool iBytes;
       
    46 	TBool iWaitOnExit;
       
    47 
       
    48 	TInt iAllocationsAccordingToRHeapWalker;
       
    49 	};
       
    50 
       
    51 EXE_BOILER_PLATE(CCmdTAllocHelper)
       
    52 
       
    53 CCommandBase* CCmdTAllocHelper::NewLC()
       
    54 	{
       
    55 	CCmdTAllocHelper* self = new(ELeave) CCmdTAllocHelper();
       
    56 	CleanupStack::PushL(self);
       
    57 	self->BaseConstructL();
       
    58 	return self;
       
    59 	}
       
    60 
       
    61 CCmdTAllocHelper::~CCmdTAllocHelper()
       
    62 	{
       
    63 	iAlloc.Close();
       
    64 	Free(iAllocations.Count());
       
    65 	iAllocations.Close();
       
    66 	}
       
    67 
       
    68 CCmdTAllocHelper::CCmdTAllocHelper()
       
    69 	: CCommandBase(EManualComplete)
       
    70 	{
       
    71 	}
       
    72 
       
    73 const TDesC& CCmdTAllocHelper::Name() const
       
    74 	{
       
    75 	_LIT(KName, "tallochelper");	
       
    76 	return KName;
       
    77 	}
       
    78 
       
    79 const TDesC& CCmdTAllocHelper::Description() const
       
    80 	{
       
    81 	_LIT(KDescription, "Test code for RAllocatorHelper");
       
    82 	return KDescription;
       
    83 	}
       
    84 
       
    85 void CCmdTAllocHelper::ArgumentsL(RCommandArgumentList& /*aArguments*/)
       
    86 	{
       
    87 	}
       
    88 
       
    89 void CCmdTAllocHelper::OptionsL(RCommandOptionList& aOptions)
       
    90 	{
       
    91 	aOptions.AppendBoolL(iBytes, 'b', _L("bytes"), _L("Display sizes in bytes rather than rounded off KB or MB"));
       
    92 	aOptions.AppendBoolL(iWaitOnExit, 'w', _L("wait"), _L("Wait indefinitely before exiting - for testing remote heap walking"));
       
    93 	}
       
    94 
       
    95 void CCmdTAllocHelper::DoRunL()
       
    96 	{
       
    97 	LeaveIfErr(iAlloc.Open(&User::Allocator()), _L("Couldn't open RAllocatorHelper"));
       
    98 	iAllocations.ReserveL(128);
       
    99 
       
   100 	Printf(_L("Udeb allocator=%d\r\n"), iAlloc.AllocatorIsUdeb());
       
   101 
       
   102 	PrintStats(_L("Initial stats"));
       
   103 	// And do an RHeap walk, just to compare
       
   104 	User::Allocator().DebugFunction(128, (TAny*)&RHeapWalkCallback, this);
       
   105 	Printf(_L("allocated size according to RHeap::Walk: %d\r\n"), iAllocationsAccordingToRHeapWalker);
       
   106 
       
   107 	AllocL(64*1024);
       
   108 	PrintStats(_L("Stats after 1 64K alloc"));
       
   109 	User::Allocator().DebugFunction(128, (TAny*)&RHeapWalkCallback, this); // debug
       
   110 
       
   111 
       
   112 	AllocL(4, 50);
       
   113 	PrintStats(_L("Stats after 50 small allocs"));
       
   114 
       
   115 	/*
       
   116 	// Open a new RAllocatorHelper cos the stats will be cached otherwise
       
   117 	RAllocatorHelper h; h.Open(&User::Allocator());
       
   118 	iAllocationsAccordingToRHeapWalker = 0;
       
   119 	User::Allocator().DebugFunction(128, (TAny*)&RHeapWalkCallback, this);
       
   120 	Printf(_L("allocated size according to RHeap::Walk: %d\r\n"), iAllocationsAccordingToRHeapWalker);
       
   121 	Printf(_L("iTotalAllocSize is %d\r\n"), h.AllocatedSize());
       
   122 	h.Close();
       
   123 	*/
       
   124 
       
   125 	if (!iWaitOnExit)
       
   126 		{
       
   127 		Free(50);
       
   128 		PrintStats(_L("Stats after freeing them"));
       
   129 		Complete();
       
   130 		}
       
   131 	}
       
   132 
       
   133 void CCmdTAllocHelper::PrintStats(const TDesC& aDesc)
       
   134 	{
       
   135 	iAlloc.RefreshDetails();
       
   136 	TBuf<16> allocSize, freeSize, dlaSize, slabSize, freeDlaSize, partiallyFreeSlabSize, freeSlabSize, pageSize;
       
   137 	FormatSize(allocSize, iAlloc.SizeForCellType(RAllocatorHelper::EAllocationMask));
       
   138 	FormatSize(freeSize, iAlloc.SizeForCellType(RAllocatorHelper::EFreeMask));
       
   139 	FormatSize(dlaSize, iAlloc.SizeForCellType(RAllocatorHelper::EDlaAllocation));
       
   140 	FormatSize(slabSize, iAlloc.SizeForCellType(RAllocatorHelper::ESlabAllocation));
       
   141 	FormatSize(freeDlaSize, iAlloc.SizeForCellType(RAllocatorHelper::EDlaFreeCell));
       
   142 	FormatSize(partiallyFreeSlabSize, iAlloc.SizeForCellType(RAllocatorHelper::ESlabFreeCell));
       
   143 	FormatSize(freeSlabSize, iAlloc.SizeForCellType(RAllocatorHelper::ESlabFreeSlab));
       
   144 	FormatSize(pageSize, iAlloc.SizeForCellType(RAllocatorHelper::EPageAllocation));
       
   145 
       
   146 	Printf(_L("\r\n%S:\r\n\
       
   147 Alloc: %d (%S), DLA: %d (%S) Slab: %d (%S) Paged: %d (%S)\r\n\
       
   148 Free: %d (%S), DLA: %d (%S) Slab: %d (%S) Free slabs: %d (%S)\r\n"), 
       
   149 		&aDesc, iAlloc.AllocationCount(), &allocSize,
       
   150 		iAlloc.CountForCellType(RAllocatorHelper::EDlaAllocation), &dlaSize,
       
   151 		iAlloc.CountForCellType(RAllocatorHelper::ESlabAllocation), &slabSize,
       
   152 		iAlloc.CountForCellType(RAllocatorHelper::EPageAllocation), &pageSize,
       
   153 		iAlloc.CountForCellType(RAllocatorHelper::EFreeMask), &freeSize,
       
   154 		iAlloc.CountForCellType(RAllocatorHelper::EDlaFreeCell), &freeDlaSize,
       
   155 		iAlloc.CountForCellType(RAllocatorHelper::ESlabFreeCell), &partiallyFreeSlabSize,
       
   156 		iAlloc.CountForCellType(RAllocatorHelper::ESlabFreeSlab), &freeSlabSize
       
   157 		);
       
   158 
       
   159 	iAlloc.Walk(&WalkCallback, this); // Check cell lengths match up
       
   160 	}
       
   161 
       
   162 void CCmdTAllocHelper::AllocL(TInt aSize, TInt aNumber)
       
   163 	{
       
   164 	while (aNumber--)
       
   165 		{
       
   166 		TAny* result = User::AllocL(aSize);
       
   167 		TInt err = iAllocations.Append(result);
       
   168 		if (err)
       
   169 			{
       
   170 			User::Free(result);
       
   171 			User::Leave(KErrNoMemory);
       
   172 			}
       
   173 		}
       
   174 	}
       
   175 
       
   176 void CCmdTAllocHelper::Free(TInt aNumber)
       
   177 	{
       
   178 	while (aNumber--)
       
   179 		{
       
   180 		TInt i = iAllocations.Count() - 1;
       
   181 		User::Free(iAllocations[i]);
       
   182 		iAllocations.Remove(i);
       
   183 		}
       
   184 	}
       
   185 
       
   186 void CCmdTAllocHelper::FormatSize(TDes& aBuf, TInt64 aSize)
       
   187 	{
       
   188 	if (iBytes)
       
   189 		{
       
   190 		aBuf.Num(aSize);
       
   191 		}
       
   192 	else
       
   193 		{
       
   194 		LtkUtils::FormatSize(aBuf, aSize);
       
   195 		}
       
   196 	}
       
   197 
       
   198 TBool CCmdTAllocHelper::WalkCallback(RAllocatorHelper& /*aAlloc*/, TAny* aContext, RAllocatorHelper::TExtendedCellType aType, TLinAddr aAddress, TInt aLength)
       
   199 	{
       
   200 	if (aType & RAllocatorHelper::EAllocationMask)
       
   201 		{
       
   202 		TInt lenFromAllocLen = User::AllocLen((TAny*)aAddress);
       
   203 		if (lenFromAllocLen != aLength)
       
   204 			{
       
   205 			static_cast<CCmdTAllocHelper*>(aContext)->PrintWarning(_L("Walker reports cell 0x%08x size %d but AllocLen says %d\r\n"), aAddress, aLength, lenFromAllocLen);
       
   206 			}
       
   207 		}
       
   208 
       
   209 	return ETrue; // Keep walking
       
   210 	}
       
   211 
       
   212 void CCmdTAllocHelper::RHeapWalkCallback(TAny* aContext, RHeap::TCellType aType, TAny* aCell, TInt aLength)
       
   213 	{
       
   214 	if (aType == RHeap::EGoodAllocatedCell)
       
   215 		{
       
   216 		CCmdTAllocHelper* self = static_cast<CCmdTAllocHelper*>(aContext);
       
   217 		self->iAllocationsAccordingToRHeapWalker += aLength;
       
   218 		}
       
   219 	}