--- a/kerneltest/e32test/heap/t_heappagealloc.cpp Tue Aug 31 16:34:26 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,462 +0,0 @@
-// 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_page_alloc.cpp
-// Overview:
-// Tests RHeap class.
-// API Information:
-// RHeap
-// Details:
-// - Tests that the page bitmap is consistent (i.e. encoded sizes are sensible and
-// encoded in the correct fashion.
-// - Tests that pages which appear in the page bitmap are present in memory by
-// reading them.
-// -Tests that other pages are not readable
-// - Tests page bitmap by creating an allocator where all allocations >= 4kB use
-// paged allocator, allocating a large number of regions of various sizes (from
-// 4 kB to b MB), checking that the walk function finds them all correctly, freeing
-// some of them, checking the walk function again, and so on.
-// Platforms/Drives/Compatibility:
-// All
-// Assumptions/Requirement/Pre-requisites:
-// Failures and causes:
-// Base Port information:
-//
-//
-
-#include <e32test.h>
-#include <e32hal.h>
-#include <e32def.h>
-#include <e32math.h>
-#include <e32def_private.h>
-#include "dla.h"
-#include "slab.h"
-#include "page_alloc.h"
-#include "heap_hybrid.h"
-
-
-struct TMetaData
- {
- TBool iDLOnly;
- RFastLock* iLock;
- TInt iChunkSize;
- TInt iSlabThreshold;
- unsigned iSlabInitThreshold;
- unsigned iSlabConfigBits;
- slab* iPartialPage;
- slab* iFullSlab;
- page* iSparePage;
- TUint8* iMemBase;
- unsigned char iSizeMap[(MAXSLABSIZE>>2)+1];
- slabset iSlabAlloc[MAXSLABSIZE>>2];
- slab** iSlabAllocRealRootAddress[MAXSLABSIZE>>2];
- };
-
-LOCAL_D RTest test(_L("T_HEAPPAGEALLOC"));
-
-class TestHybridHeap
- {
-public:
- static TUint8* MemBase(const RHybridHeap * aHybridHeap);
- static void GetHeapMetaData(RHeap& aHeap, TMetaData& aMeta);
- };
-
-TUint8* TestHybridHeap::MemBase(const RHybridHeap * aHybridHeap)
- {
- return aHybridHeap->iMemBase;
- }
-
-void TestHybridHeap::GetHeapMetaData(RHeap& aHeap, TMetaData& aMeta)
-{
- RHybridHeap::STestCommand cmd;
- cmd.iCommand = RHybridHeap::EHeapMetaData;
- TInt ret = aHeap.DebugFunction(RHeap::EHybridHeap, &cmd, 0);
- test(ret == KErrNone);
-
- RHybridHeap* hybridHeap = (RHybridHeap*) cmd.iData;
-
- aMeta.iDLOnly = hybridHeap->iDLOnly;
- aMeta.iLock = &hybridHeap->iLock;
- aMeta.iChunkSize = hybridHeap->iChunkSize;
- aMeta.iSlabThreshold = hybridHeap->iSlabThreshold;
- aMeta.iSlabInitThreshold = hybridHeap->iSlabInitThreshold;
- aMeta.iSlabConfigBits = hybridHeap->iSlabConfigBits;
- aMeta.iPartialPage = hybridHeap->iPartialPage;
- aMeta.iFullSlab = hybridHeap->iFullSlab;
- aMeta.iSparePage = hybridHeap->iSparePage;
- aMeta.iMemBase = hybridHeap->iMemBase;
-
- TInt i;
- TInt count;
- count = sizeof(aMeta.iSizeMap)/sizeof(unsigned char);
- for (i=0; i<count; ++i)
- {
- aMeta.iSizeMap[i] = hybridHeap->iSizeMap[i];
- }
- count = sizeof(aMeta.iSlabAlloc)/sizeof(slabset);
- for (i=0; i<count; ++i)
- {
- aMeta.iSlabAlloc[i].iPartial = hybridHeap->iSlabAlloc[i].iPartial;
- aMeta.iSlabAllocRealRootAddress[i] = &hybridHeap->iSlabAlloc[i].iPartial;
- }
-}
-
-LOCAL_C void GetMeta(RHeap& aHeap, TMetaData& aMeta)
-{
- TestHybridHeap::GetHeapMetaData(aHeap, aMeta);
-}
-
-class TestRHeap : public RHeap
- {
-public:
- void InitTests();
- void Test1(void);
- void Test2(void);
- void Test3(void);
- void CloseTests();
- TUint GetRandomSize(TUint aMaxSize);
- TUint GetRandomIndex(TUint aMaxIndex);
- static void WalkCallback(TAny* aPtr, TCellType aType, TAny* aCell, TInt aLen);
- TBool CheckWalkArrayEmpty();
-
-private:
- RHybridHeap* iHybridHeap;
- RHeap *iHeap;
- TUint8* iMemBase; // bottom of Paged/Slab memory (chunk base)
- static TUint iWalkArraySize;
- static TUint iWalkArrayIndex;
- static TAny** iWalkArrayOfCells;
- TUint iAllocatedArrayIndex;
- TAny** iAllocatedArrayOfCells;
- };
-
-TUint TestRHeap::iWalkArraySize = 100;
-TUint TestRHeap::iWalkArrayIndex = 0;
-TAny** TestRHeap::iWalkArrayOfCells = new TAny*[iWalkArraySize];
-
-void TestRHeap::InitTests()
-{
- // Allocate a chunk heap
- TPtrC testHeap=_L("TESTHEAP");
- iHeap=User::ChunkHeap(&testHeap,0x1800,0x800000);
- RHybridHeap::STestCommand cmd;
- cmd.iCommand = RHybridHeap::EHeapMetaData;
- iHeap->DebugFunction(RHeap::EHybridHeap, &cmd, 0);
- iHybridHeap = (RHybridHeap*) cmd.iData;
- iMemBase = TestHybridHeap::MemBase(iHybridHeap);
-
- // configure paged heap threshold 16 kB
- cmd.iCommand = RHybridHeap::ESetConfig;
- cmd.iConfig.iSlabBits = 0x0; //0xabe
- cmd.iConfig.iDelayedSlabThreshold = 0x40000000;
- cmd.iConfig.iPagePower = 14;
- test(iHeap->DebugFunction(RHeap::EHybridHeap, &cmd, 0) == KErrNone);
-}
-
-
-TUint TestRHeap::GetRandomSize(TUint aMaxSize)
-{
- TUint size = 0;
- do
- {
- size = Math::Random() & aMaxSize;
- }
- while(size < 16384 || size > aMaxSize );
- // subtract debug header size
- return size - 8;
-}
-
-
-TUint TestRHeap::GetRandomIndex(TUint aMaxIndex)
-{
- TUint index = 0;
- do
- {
- index = Math::Random() & 0x7F;
- }
- while(index >= aMaxIndex || iWalkArrayOfCells[index] == 0);
-
- return index;
-}
-
-
-void TestRHeap::WalkCallback(TAny* aPtr, TCellType aCellType, TAny* aBuffer, TInt aLen)
-{
- if (aLen>16375 && aPtr>0) // Don't test DL allocator
- test(aCellType == EGoodAllocatedCell);
-
- TUint i = 0;
- for(i=0; i<iWalkArrayIndex; i++)
- {
- if(iWalkArrayOfCells[i] == aBuffer)
- {
- iWalkArrayOfCells[i] = NULL;
- break;
- }
- }
-}
-
-TBool TestRHeap::CheckWalkArrayEmpty()
-{
- TUint i = 0;
- for(i=0; i<iWalkArrayIndex; i++)
- {
- if(iWalkArrayOfCells[i])
- {
- return EFalse;
- }
- }
- return ETrue;
-}
-
-
-///////////////////////////////////////////////////////////
-// Test page allocation with various sizes, 16 kB - 8 MB //
-// Simple test with fixed sizes. //
-///////////////////////////////////////////////////////////
-void TestRHeap::Test1(void)
-{
- // Allocate and free single paged buffers of different size
- // Small buffer
- TAny* p1 = NULL;
- p1=iHeap->Alloc(0x4000);
- test(p1 != NULL && p1 >= iMemBase && p1 < iHybridHeap);
- test(iHeap->Count() == 1);
- iHeap->Free(p1);
- p1 = NULL;
- test(iHeap->Count() == 0);
-
- // Medium buffer
- p1=iHeap->Alloc(0x20000);
- test(p1 != NULL && p1 >= iMemBase && p1 < iHybridHeap);
- test(iHeap->Count() == 1);
- iHeap->Free(p1);
- p1 = NULL;
- test(iHeap->Count() == 0);
-
- // Large buffer
- p1=iHeap->Alloc(0x700000);
- test(p1 != NULL && p1 >= iMemBase && p1 < iHybridHeap);
- test(iHeap->Count() == 1);
- iHeap->Free(p1);
- p1 = NULL;
- test(iHeap->Count() == 0);
-
- // Oversized buffer, not allocated
- p1=iHeap->Alloc(0x900000);
- test(p1 == NULL);
- test(iHeap->Count() == 0);
-}
-
-
-///////////////////////////////////////////////////////////////////////////
-// Allocate and free multiple random sized buffers, sizes under 65 kB. //
-// Check that all are allocated succesfully with Count. Free every other //
-// of them, check the Count. Allocate more buffers sized under 655 kB //
-// and free all buffers in reverse order. Check all are freed. //
-///////////////////////////////////////////////////////////////////////////
-void TestRHeap::Test2(void)
-{
- TInt ArraySize=10;
- TInt ArrayIndex;
- TAny** ArrayOfCells;
- ArrayOfCells = new TAny*[ArraySize];
-
- // Allocate set of buffers
- for(ArrayIndex=0; ArrayIndex<ArraySize; ArrayIndex++)
- {
- ArrayOfCells[ArrayIndex] = 0;
- ArrayOfCells[ArrayIndex] = iHeap->Alloc(GetRandomSize(0xFFFF));
- test(ArrayOfCells[ArrayIndex] != NULL);
- }
- test(iHeap->Count() == 10);
-
- // Free every other
- for(ArrayIndex=0; ArrayIndex<ArraySize; ArrayIndex=ArrayIndex+2 )
- {
- iHeap->Free(ArrayOfCells[ArrayIndex]);
- ArrayOfCells[ArrayIndex] = 0;
- }
- test(iHeap->Count() == 5);
-
- TInt ArraySize2=10;
- TInt ArrayIndex2;
- TAny** ArrayOfCells2;
- ArrayOfCells2 = new TAny*[ArraySize2];
-
- // Allocate larger buffers
- for(ArrayIndex2=0; ArrayIndex2<ArraySize; ArrayIndex2++)
- {
- ArrayOfCells2[ArrayIndex2] = 0;
- ArrayOfCells2[ArrayIndex2] = iHeap->Alloc(GetRandomSize(0x7FFFF));
- test(ArrayOfCells2[ArrayIndex2] != NULL);
- }
- test(iHeap->Count() == 15);
-
- // Free all buffers in reverse order
- for(ArrayIndex=9; ArrayIndex>=0; ArrayIndex-- )
- {
- if(ArrayOfCells[ArrayIndex] != 0)
- {
- iHeap->Free(ArrayOfCells[ArrayIndex]);
- ArrayOfCells[ArrayIndex] = 0;
- }
- }
- for(ArrayIndex2=9; ArrayIndex2>=0; ArrayIndex2-- )
- {
- if(ArrayOfCells2[ArrayIndex2] != 0)
- {
- iHeap->Free(ArrayOfCells2[ArrayIndex2]);
- ArrayOfCells2[ArrayIndex2] = 0;
- }
- }
- test(iHeap->Count() == 0);
-}
-
-
-///////////////////////////////////////////////////////////////////////
-// Allocate and free multiple random sized buffers. Use //
-// DebugFunction(EWalk) to check that all allocated cells are found. //
-///////////////////////////////////////////////////////////////////////
-void TestRHeap::Test3(void)
-{
- TUint iAllocatedArraySize = 100;
- iAllocatedArrayOfCells = new TAny*[iAllocatedArraySize];
-
- // allocate 100 random cells and save them in iAllocatedArrayOfCells
- for(iAllocatedArrayIndex=0; iAllocatedArrayIndex<iAllocatedArraySize; iAllocatedArrayIndex++)
- {
- iAllocatedArrayOfCells[iAllocatedArrayIndex] = 0;
- iAllocatedArrayOfCells[iAllocatedArrayIndex] = iHeap->Alloc(GetRandomSize(0xFFFF));
- test(iAllocatedArrayOfCells[iAllocatedArrayIndex] != NULL);
- }
- test(iHeap->Count() == 100); //check that all 100 allocations have succeedeed
-
- // copy iAllocatedArrayOfCells => iWalkArrayOfCells
- iWalkArrayOfCells = new TAny*[iWalkArrayIndex];
- for(iWalkArrayIndex=0; iWalkArrayIndex<iWalkArraySize; iWalkArrayIndex++)
- {
- iWalkArrayOfCells[iWalkArrayIndex] = 0;
- iWalkArrayOfCells[iWalkArrayIndex] = iAllocatedArrayOfCells[iWalkArrayIndex];
- test(iWalkArrayOfCells[iWalkArrayIndex] == iAllocatedArrayOfCells[iWalkArrayIndex]);
- }
-
- //check that walk finds all allocated cells...
- iHeap->DebugFunction(EWalk, (TAny*)&WalkCallback, (TAny*)this);
- TBool ret = CheckWalkArrayEmpty();
- test(ret); // ...and iWalkArrayOfCells is emptied
-
- // copy iAllocatedArrayOfCells => iWalkArrayOfCells
- iWalkArrayOfCells = new TAny*[iWalkArrayIndex];
- for(iWalkArrayIndex=0; iWalkArrayIndex<iWalkArraySize; iWalkArrayIndex++)
- {
- iWalkArrayOfCells[iWalkArrayIndex] = 0;
- iWalkArrayOfCells[iWalkArrayIndex] = iAllocatedArrayOfCells[iWalkArrayIndex];
- test(iWalkArrayOfCells[iWalkArrayIndex] == iAllocatedArrayOfCells[iWalkArrayIndex]);
- }
-
- // free 40 random cells from iWalkArrayOfCells
- TUint i;
- for (i=0; i<40; i++)
- {
- TUint RandomIndex = GetRandomIndex(99);
- iHeap->Free(iWalkArrayOfCells[RandomIndex]);
- iWalkArrayOfCells[RandomIndex] = 0;
- iAllocatedArrayOfCells[RandomIndex] = 0;
- }
- test(iHeap->Count() == 60);
-
- //check that walk finds all the remaining allocated cells...
- iHeap->DebugFunction(EWalk, (TAny*)&WalkCallback, (TAny*)this);
- ret = CheckWalkArrayEmpty();
- test(ret); // ...and iWalkArrayOfCells is emptied
-
- // allocate 20 more random cells starting on the first available free cell
- iAllocatedArrayIndex = 0;
- for (i=0; i<20; i++)
- {
- while (iAllocatedArrayOfCells[iAllocatedArrayIndex] != 0)
- {
- iAllocatedArrayIndex++;
- }
- iAllocatedArrayOfCells[iAllocatedArrayIndex] = iHeap->Alloc(GetRandomSize(0xFFFF));
- }
- test(iHeap->Count() == 80);
-
- // copy iAllocatedArrayOfCells => iWalkArrayOfCells
- iWalkArrayOfCells = new TAny*[iWalkArrayIndex];
- for(iWalkArrayIndex=0; iWalkArrayIndex<iWalkArraySize; iWalkArrayIndex++)
- {
- iWalkArrayOfCells[iWalkArrayIndex] = 0;
- iWalkArrayOfCells[iWalkArrayIndex] = iAllocatedArrayOfCells[iWalkArrayIndex];
- test(iWalkArrayOfCells[iWalkArrayIndex] == iAllocatedArrayOfCells[iWalkArrayIndex]);
- }
-
- //check that walk finds all the earlier and newly allocated cells...
- iHeap->DebugFunction(EWalk, (TAny*)&WalkCallback, (TAny*)this);
- ret = CheckWalkArrayEmpty();
- test(ret); // ...and iWalkArrayOfCells is emptied
-}
-
-
-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("Page Allocator Test"));
-
- TPtrC testHeapM=_L("TESTHEAP-MAIN");
- RHeap* iHeapM;
-
- iHeapM=User::ChunkHeap(&testHeapM,0x1800,0x800000);
-
- TMetaData metaData;
- GetMeta(*iHeapM, metaData);
-
- iHeapM->Close();
-
- if (metaData.iDLOnly)
- {
- test.Printf(_L("Page allocator is not used, no tests to run.\n"));
- __KHEAP_MARKEND;
- test.End();
- return(0);
- }
-
- test.Next(_L("Init Paged allocator tests"));
- T.InitTests();
- test.Next(_L("Test Paged allocator 1"));
- T.Test1();
- test.Next(_L("Test Paged allocator 2"));
- T.Test2();
- test.Next(_L("Test Paged allocator 3"));
- T.Test3();
- T.CloseTests();
-
- __KHEAP_CHECK(0);
- __KHEAP_MARKEND;
-
- test.End();
-
- return (0);
- }