diff -r a232af6b0b1f -r a5496987b1da kerneltest/e32test/heap/t_heapdl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/heap/t_heapdl.cpp Thu Jul 01 17:57:33 2010 +0100 @@ -0,0 +1,495 @@ +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "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: +// e32test\heap\t_heapdl.cpp +// Overview: +// Tests RHybridHeap class. +// API Information: +// RHybridHeap +// Details: +// +// + +#include +#include +#include +#include "dla.h" +#include "slab.h" +#include "page_alloc.h" +#include "heap_hybrid.h" + +const TInt KHeadSize = (TInt)RHeap::EAllocCellSize; + +class TestHybridHeap + { +public: + static void TopSize(TInt& aTopSize, const RHybridHeap * aHybridHeap); + static void DvSize(TInt& aDvSize, const RHybridHeap * aHybridHeap); + static void SmallMap(TUint& aSmallMap, const RHybridHeap * aHybridHeap); + static void TreeMap(TUint& aTreeMap, const RHybridHeap * aHybridHeap); + static void TrimCheck(TInt& aTrimCheck, const RHybridHeap * aHybridHeap); + static void GrowBy(TInt& aGrowBy, const RHybridHeap * aHybridHeap); + static void PageSize(TInt& aPageSize, const RHybridHeap * aHybridHeap); + }; + + +void TestHybridHeap::TopSize(TInt& aTopSize, const RHybridHeap * aHybridHeap) + { + aTopSize = aHybridHeap->iGlobalMallocState.iTopSize; + } + + +void TestHybridHeap::DvSize(TInt& aDvSize, const RHybridHeap * aHybridHeap) + { + aDvSize = aHybridHeap->iGlobalMallocState.iDvSize; + } + + +void TestHybridHeap::SmallMap(TUint& aSmallMap, const RHybridHeap * aHybridHeap) + { + aSmallMap = aHybridHeap->iGlobalMallocState.iSmallMap; + } + + +void TestHybridHeap::TreeMap(TUint& aTreeMap, const RHybridHeap * aHybridHeap) + { + aTreeMap = aHybridHeap->iGlobalMallocState.iTreeMap; + } + + +void TestHybridHeap::TrimCheck(TInt& aTrimCheck, const RHybridHeap * aHybridHeap) + { + aTrimCheck = aHybridHeap->iGlobalMallocState.iTrimCheck; + } + + +void TestHybridHeap::GrowBy(TInt& aGrowBy, const RHybridHeap * aHybridHeap) + { + aGrowBy = aHybridHeap->iGrowBy; + } + +void TestHybridHeap::PageSize(TInt& aPageSize, const RHybridHeap * aHybridHeap) + { + aPageSize = aHybridHeap->iPageSize; + } + + +LOCAL_D RTest test(_L("T_HEAPDL")); + + +class TestRHeap + { +public: + void InitTests(); + void Test1(void); + void Test2(void); + void Test3(void); + void Test4(void); + void CloseTests(); +private: + RHybridHeap* iHybridHeap; + RHeap *iHeap; + }; + + +void TestRHeap::InitTests() + { + // Allocate a chunk heap + TPtrC testHeap=_L("TESTHEAP"); + iHeap=User::ChunkHeap(&testHeap,0x1800,0x16000); + + RHybridHeap::STestCommand cmd; + cmd.iCommand = RHybridHeap::EHeapMetaData; + iHeap->DebugFunction(RHeap::EHybridHeap, (TAny*)&cmd ); + iHybridHeap = (RHybridHeap*) cmd.iData; + } + + +void TestRHeap::Test1(void) + { + // + // Splitting a new cell off 'top' chunk + // Growing and shrinking 'top' chunk + // Coalesceing of adjacent free cells + // + + TInt topSizeBefore, topSizeAfter, allocSize; + TInt growBy, pageSize; + TestHybridHeap::GrowBy(growBy,iHybridHeap); + TestHybridHeap::PageSize(pageSize,iHybridHeap); + + //Splitting a new cell off 'top' chunk + TestHybridHeap::TopSize(topSizeBefore,iHybridHeap); + TAny* p1=iHeap->Alloc(0x256); + TestHybridHeap::TopSize(topSizeAfter,iHybridHeap); + test(topSizeBefore > topSizeAfter); + iHeap->Check(); + iHeap->Free(p1); + iHeap->Check(); + + //Growing 'top' chunk + test(iHeap!=NULL); + TestHybridHeap::TopSize(topSizeBefore,iHybridHeap); + p1=iHeap->Alloc(pageSize*2); + test(p1!=NULL); + allocSize=iHeap->AllocLen(p1); + TestHybridHeap::TopSize(topSizeAfter,iHybridHeap); + test(topSizeBefore + growBy == topSizeAfter+allocSize+KHeadSize); + + //Splitting a new cell off 'top' chunk + TAny *p2=iHeap->Alloc(pageSize/8); + test(p2!=NULL); + //Splitting a new cell off 'top' chunk + TAny *p3=iHeap->Alloc(pageSize/2); + test(p3!=NULL); + //Growing 'top' chunk + TAny *p4=iHeap->Alloc(pageSize*2); + test(p4!=NULL); + //Take allocSize of p4 + allocSize=iHeap->AllocLen(p4); + + //Shrinking 'top' chunk + TInt trimCheck; + TestHybridHeap::TopSize(topSizeBefore,iHybridHeap); + iHeap->Free(p4); + TestHybridHeap::TopSize(topSizeAfter,iHybridHeap); + TestHybridHeap::TrimCheck(trimCheck,iHybridHeap); + test(topSizeAfter + trimCheck == topSizeBefore+allocSize+KHeadSize); + iHeap->Check(); + + //Insert chunk into treebin + TUint treeMap,treeMap2; + TestHybridHeap::TreeMap(treeMap,iHybridHeap); + test(treeMap==0); + iHeap->Free(p2); + TestHybridHeap::TreeMap(treeMap,iHybridHeap); + test(treeMap>0); + iHeap->Check(); + + //Coalesce adjacent free cells and insert chunk into treebin + TestHybridHeap::TreeMap(treeMap,iHybridHeap); + iHeap->Free(p1); + TestHybridHeap::TreeMap(treeMap2,iHybridHeap); + test(treeMap < treeMap2); + iHeap->Check(); + + //free last allocation + iHeap->Free(p3); + iHeap->Check(); + } + + +void TestRHeap::Test2(void) + { + // + // Allocation of exact sized cells from 'small cell' lists (smallbin) + // Freeing of exact sized cells back to 'small cell' lists (smallbin) + // + TInt ArraySize=32; + TInt cellSize=0; + TInt topSizeBefore, topSizeAfter; + + TAny** ArrayOfCells; + ArrayOfCells= new TAny*[ArraySize]; + TInt ArrayIndex; + // Allocate exact sized small cells 8,16,32,40---> + // and put them to the array. They are allocated from TOP chunk + for(ArrayIndex=0; ArrayIndexAlloc(cellSize); + TestHybridHeap::TopSize(topSizeAfter,iHybridHeap); + test(topSizeBefore > topSizeAfter); + } + iHeap->Check(); + + TUint smallMap, smallMap2; + TInt dvSize, dvSize2; + TestHybridHeap::SmallMap(smallMap,iHybridHeap); + test(smallMap == 0); + // Free some of small cells from the array. So they are inserted + // to the smallbin + for(ArrayIndex=2; ArrayIndexFree(ArrayOfCells[ArrayIndex]); + TestHybridHeap::SmallMap(smallMap2,iHybridHeap); + test(smallMapCheck(); + + // Allocate exact sized cells from smallbin (or Designated Victim) + TestHybridHeap::SmallMap(smallMap,iHybridHeap); + TAny* p1=iHeap->Alloc(32); + TestHybridHeap::SmallMap(smallMap2,iHybridHeap); + test(smallMap>smallMap2); + + TestHybridHeap::SmallMap(smallMap,iHybridHeap); + TestHybridHeap::DvSize(dvSize,iHybridHeap); + TAny* p2=iHeap->Alloc(32); + TestHybridHeap::SmallMap(smallMap2,iHybridHeap); + TestHybridHeap::DvSize(dvSize2,iHybridHeap); + if(dvSize <= dvSize2) + test(smallMap>smallMap2); + + TestHybridHeap::SmallMap(smallMap,iHybridHeap); + TestHybridHeap::DvSize(dvSize,iHybridHeap); + TAny* p3=iHeap->Alloc(32); + TestHybridHeap::SmallMap(smallMap2,iHybridHeap); + TestHybridHeap::DvSize(dvSize2,iHybridHeap); + if(dvSize <= dvSize2) + test(smallMap>smallMap2); + + TestHybridHeap::SmallMap(smallMap,iHybridHeap); + TestHybridHeap::DvSize(dvSize,iHybridHeap); + TAny* p4=iHeap->Alloc(32); + TestHybridHeap::SmallMap(smallMap2,iHybridHeap); + TestHybridHeap::DvSize(dvSize2,iHybridHeap); + if(dvSize <= dvSize2) + test(smallMap>smallMap2); + + TestHybridHeap::SmallMap(smallMap,iHybridHeap); + TestHybridHeap::DvSize(dvSize,iHybridHeap); + TAny* p5=iHeap->Alloc(48); + TestHybridHeap::SmallMap(smallMap2,iHybridHeap); + TestHybridHeap::DvSize(dvSize2,iHybridHeap); + if(dvSize <= dvSize2) + test(smallMap>smallMap2); + + TestHybridHeap::SmallMap(smallMap,iHybridHeap); + TestHybridHeap::DvSize(dvSize,iHybridHeap); + TAny* p6=iHeap->Alloc(64); + TestHybridHeap::SmallMap(smallMap2,iHybridHeap); + TestHybridHeap::DvSize(dvSize2,iHybridHeap); + if(dvSize <= dvSize2) + test(smallMap>smallMap2); + + TestHybridHeap::SmallMap(smallMap,iHybridHeap); + TestHybridHeap::DvSize(dvSize,iHybridHeap); + TAny* p7=iHeap->Alloc(80); + TestHybridHeap::SmallMap(smallMap2,iHybridHeap); + TestHybridHeap::DvSize(dvSize2,iHybridHeap); + if(dvSize <= dvSize2) + test(smallMap>smallMap2); + + TestHybridHeap::SmallMap(smallMap,iHybridHeap); + TestHybridHeap::DvSize(dvSize,iHybridHeap); + TAny* p8=iHeap->Alloc(96); + TestHybridHeap::SmallMap(smallMap2,iHybridHeap); + TestHybridHeap::DvSize(dvSize2,iHybridHeap); + if(dvSize <= dvSize2) + test(smallMap>smallMap2); + iHeap->Check(); + + // Freeing of exact sized cells back to smallbin + TestHybridHeap::SmallMap(smallMap,iHybridHeap); + iHeap->Free(p1); + iHeap->Free(p2); + iHeap->Free(p3); + iHeap->Free(p4); + iHeap->Free(p5); + iHeap->Free(p6); + iHeap->Free(p7); + iHeap->Free(p8); + TestHybridHeap::SmallMap(smallMap2,iHybridHeap); + test(smallMap < smallMap2); + iHeap->Check(); + + // Now free rest of the array with Reset + iHeap->Reset(); + iHeap->Check(); + + delete [] ArrayOfCells; + } + + +void TestRHeap::Test3(void) + { + // + // Allocation of approximate sized cells from 'small cell' lists (smallbin) + // + TInt ArraySize=32; + TInt cellSize=0; + TAny** ArrayOfCells; + ArrayOfCells= new TAny*[ArraySize]; + TInt ArrayIndex; + TInt topSizeBefore, topSizeAfter; + + // Allocate small approximate sized cells and put + //them to the array. They are allocated from TOP chunk + TUint8 randomSize; + for(ArrayIndex=0; ArrayIndex240); + + cellSize=randomSize; + ArrayOfCells[ArrayIndex]=iHeap->Alloc(cellSize); + TestHybridHeap::TopSize(topSizeAfter,iHybridHeap); + test(topSizeBefore > topSizeAfter); + } + iHeap->Check(); + + TUint smallMap, smallMap2; + // Free some of allocated cells from the array. So they are inserted + // to the smallbin + TestHybridHeap::SmallMap(smallMap,iHybridHeap); + for(ArrayIndex=2; ArrayIndexFree(ArrayOfCells[ArrayIndex]); + } + TestHybridHeap::SmallMap(smallMap2,iHybridHeap); + test(smallMap<=smallMap2); + iHeap->Check(); + + // Allocate approximate sized cells from smallbin + TInt ArraySize2=6; + TInt cellSize2=0; + TAny** ArrayOfCells2; + ArrayOfCells2= new TAny*[ArraySize2]; + TInt ArrayIndex2; + TestHybridHeap::SmallMap(smallMap,iHybridHeap); + for(ArrayIndex2=0; ArrayIndex2Alloc(cellSize2); + } + TestHybridHeap::SmallMap(smallMap2,iHybridHeap); + test(smallMap>=smallMap2); + iHeap->Check(); + + // Freeing of approximate sized cells back to smallbin + for(ArrayIndex2=0; ArrayIndex2Free(ArrayOfCells2[ArrayIndex2]); + } + iHeap->Check(); + + // Now free rest of the array with Reset + iHeap->Reset(); + iHeap->Check(); + + delete [] ArrayOfCells; + delete [] ArrayOfCells2; + } + + +void TestRHeap::Test4(void) + { + // + // Allocation of approximate sized cells from digital trees (treebin) and splitting + // Freeing of approximate sized cells back to digital trees (treebin) + // + TInt ArraySize=32; + TInt cellSize=0; + TAny** ArrayOfCells; + ArrayOfCells= new TAny*[ArraySize]; + TInt ArrayIndex; + + // Allocate approximate sized cells bigger than 256 + // and put them to the array. They are allocated from TOP chunk + for(ArrayIndex=0; ArrayIndexAlloc(cellSize); + } + iHeap->Check(); + + TUint treeMap,treeMap2; + // Free some of allocated cells from the array. So they are inserted + // to the treebin + for(ArrayIndex=2; ArrayIndexFree(ArrayOfCells[ArrayIndex]); + TestHybridHeap::TreeMap(treeMap2,iHybridHeap); + test(treeMap <= treeMap2); + } + iHeap->Check(); + + // Allocate approximate sized cells from treebin + TInt ArraySize2=16; + TInt cellSize2=0; + TAny** ArrayOfCells2; + ArrayOfCells2= new TAny*[ArraySize2]; + TInt ArrayIndex2; + for(ArrayIndex2=0; ArrayIndex2Alloc(cellSize2); + TestHybridHeap::TreeMap(treeMap2,iHybridHeap); + test(treeMap >= treeMap2); + } + iHeap->Check(); + + // Freeing of approximate sized cells back to treebin + TestHybridHeap::TreeMap(treeMap,iHybridHeap); + for(ArrayIndex2=0; ArrayIndex2Free(ArrayOfCells2[ArrayIndex2]); + } + TestHybridHeap::TreeMap(treeMap2,iHybridHeap); + test(treeMap <= treeMap2); + iHeap->Check(); + + // Now free rest of the array with Reset + iHeap->Reset(); + iHeap->Check(); + + delete [] ArrayOfCells; + delete [] ArrayOfCells2; + } + + +void TestRHeap::CloseTests() + { + // close heap so we don't exceed chunk limit + iHeap->Close(); + } + + +GLDEF_C TInt E32Main(void) + { + test.Title(); + + __KHEAP_MARK; + + TestRHeap T; + test.Start(_L("Init DL allocator tests")); + T.InitTests(); + test.Next(_L("Test DL allocator 1")); + T.Test1(); + test.Next(_L("Test DL allocator 2")); + T.Test2(); + test.Next(_L("Test DL allocator 3")); + T.Test3(); + test.Next(_L("Test DL allocator 4")); + T.Test4(); + test.Next(_L("Close DL allocator tests")); + T.CloseTests(); + + __KHEAP_CHECK(0); + __KHEAP_MARKEND; + + test.End(); + return(0); + }