--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libraries/ltkutils/tsrc/tallochelper.cpp Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,219 @@
+// tallochelper.cpp
+//
+// Copyright (c) 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "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:
+// Accenture - Initial contribution
+//
+
+#include <fshell/ioutils.h>
+#include <fshell/common.mmh>
+#include <fshell/heaputils.h>
+#include <fshell/ltkutils.h>
+
+using namespace IoUtils;
+using LtkUtils::RAllocatorHelper;
+
+class CCmdTAllocHelper : public CCommandBase
+ {
+public:
+ static CCommandBase* NewLC();
+ ~CCmdTAllocHelper();
+private:
+ CCmdTAllocHelper();
+ void PrintStats(const TDesC& aDesc);
+
+ void AllocL(TInt aSize, TInt aNumber=1);
+ void Free(TInt aNumber=1);
+ void FormatSize(TDes& aBuf, TInt64 aSize);
+ static TBool WalkCallback(RAllocatorHelper& aAlloc, TAny* aContext, RAllocatorHelper::TExtendedCellType aType, TLinAddr aAddress, TInt aLength);
+ static void RHeapWalkCallback(TAny* aContext, RHeap::TCellType aType, TAny* aCell, TInt aLength);
+
+private: // From CCommandBase.
+ virtual const TDesC& Name() const;
+ virtual const TDesC& Description() const;
+ virtual void DoRunL();
+ virtual void ArgumentsL(RCommandArgumentList& aArguments);
+ virtual void OptionsL(RCommandOptionList& aOptions);
+private:
+ RAllocatorHelper iAlloc;
+ RArray<TAny*> iAllocations;
+ TBool iBytes;
+ TBool iWaitOnExit;
+
+ TInt iAllocationsAccordingToRHeapWalker;
+ };
+
+EXE_BOILER_PLATE(CCmdTAllocHelper)
+
+CCommandBase* CCmdTAllocHelper::NewLC()
+ {
+ CCmdTAllocHelper* self = new(ELeave) CCmdTAllocHelper();
+ CleanupStack::PushL(self);
+ self->BaseConstructL();
+ return self;
+ }
+
+CCmdTAllocHelper::~CCmdTAllocHelper()
+ {
+ iAlloc.Close();
+ Free(iAllocations.Count());
+ iAllocations.Close();
+ }
+
+CCmdTAllocHelper::CCmdTAllocHelper()
+ : CCommandBase(EManualComplete)
+ {
+ }
+
+const TDesC& CCmdTAllocHelper::Name() const
+ {
+ _LIT(KName, "tallochelper");
+ return KName;
+ }
+
+const TDesC& CCmdTAllocHelper::Description() const
+ {
+ _LIT(KDescription, "Test code for RAllocatorHelper");
+ return KDescription;
+ }
+
+void CCmdTAllocHelper::ArgumentsL(RCommandArgumentList& /*aArguments*/)
+ {
+ }
+
+void CCmdTAllocHelper::OptionsL(RCommandOptionList& aOptions)
+ {
+ aOptions.AppendBoolL(iBytes, 'b', _L("bytes"), _L("Display sizes in bytes rather than rounded off KB or MB"));
+ aOptions.AppendBoolL(iWaitOnExit, 'w', _L("wait"), _L("Wait indefinitely before exiting - for testing remote heap walking"));
+ }
+
+void CCmdTAllocHelper::DoRunL()
+ {
+ LeaveIfErr(iAlloc.Open(&User::Allocator()), _L("Couldn't open RAllocatorHelper"));
+ iAllocations.ReserveL(128);
+
+ Printf(_L("Udeb allocator=%d\r\n"), iAlloc.AllocatorIsUdeb());
+
+ PrintStats(_L("Initial stats"));
+ // And do an RHeap walk, just to compare
+ User::Allocator().DebugFunction(128, (TAny*)&RHeapWalkCallback, this);
+ Printf(_L("allocated size according to RHeap::Walk: %d\r\n"), iAllocationsAccordingToRHeapWalker);
+
+ AllocL(64*1024);
+ PrintStats(_L("Stats after 1 64K alloc"));
+ User::Allocator().DebugFunction(128, (TAny*)&RHeapWalkCallback, this); // debug
+
+
+ AllocL(4, 50);
+ PrintStats(_L("Stats after 50 small allocs"));
+
+ /*
+ // Open a new RAllocatorHelper cos the stats will be cached otherwise
+ RAllocatorHelper h; h.Open(&User::Allocator());
+ iAllocationsAccordingToRHeapWalker = 0;
+ User::Allocator().DebugFunction(128, (TAny*)&RHeapWalkCallback, this);
+ Printf(_L("allocated size according to RHeap::Walk: %d\r\n"), iAllocationsAccordingToRHeapWalker);
+ Printf(_L("iTotalAllocSize is %d\r\n"), h.AllocatedSize());
+ h.Close();
+ */
+
+ if (!iWaitOnExit)
+ {
+ Free(50);
+ PrintStats(_L("Stats after freeing them"));
+ Complete();
+ }
+ }
+
+void CCmdTAllocHelper::PrintStats(const TDesC& aDesc)
+ {
+ iAlloc.RefreshDetails();
+ TBuf<16> allocSize, freeSize, dlaSize, slabSize, freeDlaSize, partiallyFreeSlabSize, freeSlabSize, pageSize;
+ FormatSize(allocSize, iAlloc.SizeForCellType(RAllocatorHelper::EAllocationMask));
+ FormatSize(freeSize, iAlloc.SizeForCellType(RAllocatorHelper::EFreeMask));
+ FormatSize(dlaSize, iAlloc.SizeForCellType(RAllocatorHelper::EDlaAllocation));
+ FormatSize(slabSize, iAlloc.SizeForCellType(RAllocatorHelper::ESlabAllocation));
+ FormatSize(freeDlaSize, iAlloc.SizeForCellType(RAllocatorHelper::EDlaFreeCell));
+ FormatSize(partiallyFreeSlabSize, iAlloc.SizeForCellType(RAllocatorHelper::ESlabFreeCell));
+ FormatSize(freeSlabSize, iAlloc.SizeForCellType(RAllocatorHelper::ESlabFreeSlab));
+ FormatSize(pageSize, iAlloc.SizeForCellType(RAllocatorHelper::EPageAllocation));
+
+ Printf(_L("\r\n%S:\r\n\
+Alloc: %d (%S), DLA: %d (%S) Slab: %d (%S) Paged: %d (%S)\r\n\
+Free: %d (%S), DLA: %d (%S) Slab: %d (%S) Free slabs: %d (%S)\r\n"),
+ &aDesc, iAlloc.AllocationCount(), &allocSize,
+ iAlloc.CountForCellType(RAllocatorHelper::EDlaAllocation), &dlaSize,
+ iAlloc.CountForCellType(RAllocatorHelper::ESlabAllocation), &slabSize,
+ iAlloc.CountForCellType(RAllocatorHelper::EPageAllocation), &pageSize,
+ iAlloc.CountForCellType(RAllocatorHelper::EFreeMask), &freeSize,
+ iAlloc.CountForCellType(RAllocatorHelper::EDlaFreeCell), &freeDlaSize,
+ iAlloc.CountForCellType(RAllocatorHelper::ESlabFreeCell), &partiallyFreeSlabSize,
+ iAlloc.CountForCellType(RAllocatorHelper::ESlabFreeSlab), &freeSlabSize
+ );
+
+ iAlloc.Walk(&WalkCallback, this); // Check cell lengths match up
+ }
+
+void CCmdTAllocHelper::AllocL(TInt aSize, TInt aNumber)
+ {
+ while (aNumber--)
+ {
+ TAny* result = User::AllocL(aSize);
+ TInt err = iAllocations.Append(result);
+ if (err)
+ {
+ User::Free(result);
+ User::Leave(KErrNoMemory);
+ }
+ }
+ }
+
+void CCmdTAllocHelper::Free(TInt aNumber)
+ {
+ while (aNumber--)
+ {
+ TInt i = iAllocations.Count() - 1;
+ User::Free(iAllocations[i]);
+ iAllocations.Remove(i);
+ }
+ }
+
+void CCmdTAllocHelper::FormatSize(TDes& aBuf, TInt64 aSize)
+ {
+ if (iBytes)
+ {
+ aBuf.Num(aSize);
+ }
+ else
+ {
+ LtkUtils::FormatSize(aBuf, aSize);
+ }
+ }
+
+TBool CCmdTAllocHelper::WalkCallback(RAllocatorHelper& /*aAlloc*/, TAny* aContext, RAllocatorHelper::TExtendedCellType aType, TLinAddr aAddress, TInt aLength)
+ {
+ if (aType & RAllocatorHelper::EAllocationMask)
+ {
+ TInt lenFromAllocLen = User::AllocLen((TAny*)aAddress);
+ if (lenFromAllocLen != aLength)
+ {
+ static_cast<CCmdTAllocHelper*>(aContext)->PrintWarning(_L("Walker reports cell 0x%08x size %d but AllocLen says %d\r\n"), aAddress, aLength, lenFromAllocLen);
+ }
+ }
+
+ return ETrue; // Keep walking
+ }
+
+void CCmdTAllocHelper::RHeapWalkCallback(TAny* aContext, RHeap::TCellType aType, TAny* aCell, TInt aLength)
+ {
+ if (aType == RHeap::EGoodAllocatedCell)
+ {
+ CCmdTAllocHelper* self = static_cast<CCmdTAllocHelper*>(aContext);
+ self->iAllocationsAccordingToRHeapWalker += aLength;
+ }
+ }