diff -r c1f20ce4abcf -r 3e88ff8f41d5 kerneltest/e32test/heap/t_heapslab.cpp --- a/kerneltest/e32test/heap/t_heapslab.cpp Tue Aug 31 16:34:26 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1056 +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_heapslab.cpp -// Overview: -// Tests RHybridHeap class: slab allocator -// API Information: -// RHybridHeap/RHeap -// Details: -//- Starts with empty allocator configured to use slab allocation -// on all cell sizes less than slab threshold (49). -//- Allocate enough cells of the same size to fill 128 slabs. -//- Check the number of pages used corresponds to the number of slabs. -//- Check that a new slab is taken from a partially filled page if available. -//- Check that a partially filled slab is used if available. -//- Check that if all four slabs in a page are free, the page is freed. -//- Free cells to give empty slab. -//- Free cells to give partial slab. -//- Reallocate cells. -//- RAllocator::Check() is used to check internal consistency. -// Platforms/Drives/Compatibility: -// All -// Assumptions/Requirement/Pre-requisites: -// Failures and causes: -// Base Port information: -// -// - -#include -#include -#include -#include -#include "dla.h" -#include "slab.h" -#include "page_alloc.h" -#include "heap_hybrid.h" - -#define MAX_THREADS 4 -#define MAX_ALLOCS 20000 // 16128, if slab count is 128 and alloc size is 8 - -//#define TSTSLAB_DBG(a) a -#define TSTSLAB_DBG(a) - -struct TSlabTestThreadParm - { - RHeap* iHeap; - TInt iAllocSize; - TInt iInitSlabCount; - TBool iUseRandomSize; - TInt iThreadCount; - TInt iThreadIndex; - }; - -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]; - }; - -class TestHybridHeap - { -public: - static void GetHeapMetaData(RHeap& aHeap, TMetaData& aMeta); - }; - -LOCAL_D RTest test(_L("T_HEAPSLAB")); - -LOCAL_D TInt PageSize; - -LOCAL_D TAny* PtrBuf[MAX_THREADS][MAX_ALLOCS]; -LOCAL_D TSlabTestThreadParm ThreadParm[MAX_THREADS]; - -enum TTestWalkFunc {ETestWalk, ETestFindSlab}; - - -static unsigned SlabHeaderPagemap(unsigned h) {return (h&0x00000f00)>>8;} - -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; iiSizeMap[i]; - } - count = sizeof(aMeta.iSlabAlloc)/sizeof(slabset); - for (i=0; iiSlabAlloc[i].iPartial; - aMeta.iSlabAllocRealRootAddress[i] = &hybridHeap->iSlabAlloc[i].iPartial; - } -} - -LOCAL_C void GetMeta(RHeap& aHeap, TMetaData& aMeta) -{ - TestHybridHeap::GetHeapMetaData(aHeap, aMeta); -} - -/*LOCAL_C void PrintMeta(const char* aText, TMetaData& aMeta) -{ - RDebug::Printf("=========== HeapMetaData (local) - begin: %s", aText); - - RDebug::Printf("iDLOnly: 0x%08x", aMeta.iDLOnly); - RDebug::Printf("iChunkSize: 0x%08x", aMeta.iChunkSize); - RDebug::Printf("iSlabThreshold: 0x%08x / %d", aMeta.iSlabThreshold, aMeta.iSlabThreshold); - RDebug::Printf("iSlabInitThreshold: 0x%08x / %d", aMeta.iSlabInitThreshold, aMeta.iSlabInitThreshold); - RDebug::Printf("iSlabConfigBits: 0x%08x", aMeta.iSlabConfigBits); - RDebug::Printf("iPartialPage: 0x%08x", aMeta.iPartialPage); - RDebug::Printf("iFullSlab: 0x%08x", aMeta.iFullSlab); - RDebug::Printf("iSparePage: 0x%08x", aMeta.iSparePage); - RDebug::Printf("iMemBase: 0x%08x", aMeta.iMemBase); - - TInt i; - TInt count; - count = sizeof(aMeta.iSizeMap)/sizeof(unsigned char); - for (i=0; i(Floor(s, PAGESIZE)); - } - - -LOCAL_C slab* SlabFor(const void* p) -{ - return (slab*)(Floor(p, SLABSIZE)); -} - -LOCAL_C TInt TreeWalk(slab** aRealRootAddress, slab* const* aRoot, TTestWalkFunc aFunc, TAny* aParm, TInt& aOutParm) -{ - TInt count = 0; - aOutParm = 0; - - slab* s = *aRoot; - if (!s) - return count; - - for (;;) - { - slab* c; - while ((c = s->iChild1) != 0) - s = c; // walk down left side to end - for (;;) - { - count++; - TSTSLAB_DBG(RDebug::Printf("TreeWalk - slab: 0x%08x", s)); - (void)aParm; - if (aFunc == ETestWalk) - { - ; - } - else if (aFunc == ETestFindSlab) - { - if ((slab*)aParm == s) - { - aOutParm = 1; - return 0; - } - } - - c = s->iChild2; - if (c) - { // one step down right side, now try and walk down left - s = c; - break; - } - for (;;) - { // loop to walk up right side - slab** pp = s->iParent; - if (pp == aRealRootAddress) - return count; - s = SlabFor(pp); - if (pp == &s->iChild1) - break; - } - } - } -} - -LOCAL_C TInt WalkSlabSet(TInt aSlabsetIndex, TMetaData& aMeta, TTestWalkFunc aFunc, TAny* aParm, TInt& aOutParm) -{ - if (aSlabsetIndex >= (MAXSLABSIZE>>2)) - { - return 0; - } - return TreeWalk(aMeta.iSlabAllocRealRootAddress[aSlabsetIndex], &aMeta.iSlabAlloc[aSlabsetIndex].iPartial, aFunc, aParm, aOutParm); -} - -/*LOCAL_C void DebugPrintSlabs(TInt aSlabsetIndex, TMetaData& aMeta) - { - //RDebug::Printf("=========== DebugPrintSlabs: %s", aText); - RDebug::Printf("=========== DebugPrintSlabs"); - - RDebug::Printf("iSparePage: 0x%08x", aMeta.iSparePage); - - slab* fullSlab = aMeta.iFullSlab; - TInt fullSlabCount = 0; - while (fullSlab) - { - RDebug::Printf("fullSlab: 0x%08x", fullSlab); - fullSlabCount++; - fullSlab = fullSlab->iChild1; - } - - TInt outParm; - TInt partialTreeSlabCount = 0; - partialTreeSlabCount += WalkSlabSet(aSlabsetIndex, aMeta, ETestWalk, 0, outParm); - - slab* partialPageSlab = aMeta.iPartialPage; - TInt partialPageSlabCount = 0; - while (partialPageSlab) - { - RDebug::Printf("partialPageSlab (empty): 0x%08x", partialPageSlab); - partialPageSlabCount++; - partialPageSlab = partialPageSlab->iChild1; - } - }*/ - -LOCAL_C void TestSlabFixedSizeManyThreads(TSlabTestThreadParm& aParm) - { - RHeap* heap = aParm.iHeap; - TInt allocSize = aParm.iAllocSize; - TInt initSlabCount = aParm.iInitSlabCount; - //TBool useRandomSize = aParm.iUseRandomSize; - //TInt threadCount = aParm.iThreadCount; - TInt threadIndex = aParm.iThreadIndex; - - TInt slabsPerPage = PageSize/SLABSIZE; - - test(initSlabCount % slabsPerPage == 0); // for this test - -#ifdef _DEBUG - TInt allocRealCellSize = allocSize + RHeap::EDebugHdrSize; -#else - TInt allocRealCellSize = allocSize; -#endif - - TMetaData metaData; - GetMeta(*heap, metaData); - - if (allocRealCellSize >= metaData.iSlabThreshold) - { - allocRealCellSize = metaData.iSlabThreshold - 1; -#ifdef _DEBUG - allocSize = allocRealCellSize - RHeap::EDebugHdrSize; -#else - allocSize = allocRealCellSize; -#endif - } - - TAny** pBuf = &PtrBuf[threadIndex][0]; - TInt i; - for (i=0; i>2]; - test(slabsetIndex != 0xff); - TInt slabCellSize = 4 + (slabsetIndex * 4); - - TInt slabPayloadSize = SLABSIZE - sizeof(slabhdr); - TInt cellCountPerSlab = slabPayloadSize / slabCellSize; - TInt initCellCount = initSlabCount * cellCountPerSlab; - - TSTSLAB_DBG(RDebug::Printf("=========== Allocate enough cells of the same size to fill %d slabs", initSlabCount)); - TSTSLAB_DBG(RDebug::Printf("=========== counts: %d %d %d", cellCountPerSlab, initCellCount, slabCellSize)); - - for (i=0; iAlloc(allocSize); - test(pBuf[i] != 0); - } - - heap->Check(); - - TInt maxI5 = initCellCount + (cellCountPerSlab*(slabsPerPage+1)); - for (i=initCellCount; iAlloc(allocSize); - test(pBuf[i] != 0); - } - - heap->Check(); - - TAny* p2 = heap->Alloc(allocSize); - test(p2 != 0); - - heap->Check(); - heap->Free(p2); - - heap->Check(); - - - TInt page2pBufIndexFirst = cellCountPerSlab * slabsPerPage; - //TInt page2pBufIndexLast = page2pBufIndexFirst + (cellCountPerSlab * slabsPerPage); - - slab* partialTreeSlabX1 = SlabFor(pBuf[page2pBufIndexFirst]); - page* partialTreeSlabPageX1 = PageFor(partialTreeSlabX1); - - heap->Free(pBuf[page2pBufIndexFirst]); - pBuf[page2pBufIndexFirst] = 0; - - heap->Check(); - - TAny* p3 = heap->Alloc(allocSize); - test(p3 != 0); - heap->Check(); - heap->Free(p3); - heap->Check(); - - TInt size2 = metaData.iChunkSize; - TSTSLAB_DBG(RDebug::Printf("---- size2: 0x%08x", size2)); - if (metaData.iSparePage) - { - size2 -= PageSize; - } - - for (i=0; iFree(pBuf[i]); - pBuf[i] = 0; - } - } - } - - heap->Check(); - - TInt size3 = metaData.iChunkSize; - if (metaData.iSparePage) - { - size3 -= PageSize; - } - - TInt bufIndexFirst = cellCountPerSlab; - TInt maxI = bufIndexFirst + cellCountPerSlab; - for (i=bufIndexFirst; i<=maxI; ++i) - { - if (pBuf[i]) - { - heap->Free(pBuf[i]); - pBuf[i] = 0; - } - } - - heap->Check(); - - TInt firstI = cellCountPerSlab * 3; - maxI = firstI + cellCountPerSlab; - for (i=firstI; i<=maxI; ++i) - { - if (i % 3 == 0) - { - if (pBuf[i]) - { - heap->Free(pBuf[i]); - pBuf[i] = 0; - } - } - } - - heap->Check(); - - //Reallocate cells. - for (i=0; i<(MAX_ALLOCS); ++i) - { - if (pBuf[i] != 0) - { - pBuf[i] = heap->ReAlloc(pBuf[i], allocSize); - test(pBuf[i] != 0); - } - } - - heap->Check(); - - //Allocate cells. - for (i=0; i<(MAX_ALLOCS/4); ++i) - { - if (pBuf[i] == 0) - { - pBuf[i] = heap->Alloc(allocSize); - test(pBuf[i] != 0); - } - } - - heap->Check(); - - for (i=0; iFree(pBuf[i]); - pBuf[i] = 0; - } - } - heap->Check(); - - TSTSLAB_DBG(RDebug::Printf("=========== TestSlabFixedSizeManyThreads end")); - } - - -LOCAL_C void TestSlabFixedSizeOneThread(TSlabTestThreadParm& aParm) - { - RHeap* heap = aParm.iHeap; - TInt allocSize = aParm.iAllocSize; - TInt initSlabCount = aParm.iInitSlabCount; - //TBool useRandomSize = aParm.iUseRandomSize; - //TInt threadCount = aParm.iThreadCount; - TInt threadIndex = aParm.iThreadIndex; - - TInt slabsPerPage = PageSize/SLABSIZE; - - test(initSlabCount % slabsPerPage == 0); // for this test - -#ifdef _DEBUG - TInt allocRealCellSize = allocSize + RHeap::EDebugHdrSize; -#else - TInt allocRealCellSize = allocSize; -#endif - - TMetaData metaData; - GetMeta(*heap, metaData); - - TSTSLAB_DBG(PrintMeta(" --- TestSlabFixedSizeOneThread start", metaData)); - - if (allocRealCellSize >= metaData.iSlabThreshold) - { - allocRealCellSize = metaData.iSlabThreshold - 1; -#ifdef _DEBUG - allocSize = allocRealCellSize - RHeap::EDebugHdrSize; -#else - allocSize = allocRealCellSize; -#endif - } - - TAny** pBuf = &PtrBuf[threadIndex][0]; - TInt i; - for (i=0; i>2]; - test(slabsetIndex != 0xff); - TInt slabCellSize = 4 + (slabsetIndex * 4); - - TInt slabPayloadSize = SLABSIZE - sizeof(slabhdr); - TInt cellCountPerSlab = slabPayloadSize / slabCellSize; - TInt initCellCount = initSlabCount * cellCountPerSlab; - - TSTSLAB_DBG(RDebug::Printf("=========== Allocate enough cells of the same size to fill %d slabs", initSlabCount)); - TSTSLAB_DBG(RDebug::Printf("=========== counts: %d %d %d", cellCountPerSlab, initCellCount, slabCellSize)); - - for (i=0; iAlloc(allocSize); - test(pBuf[i] != 0); - } - - heap->Check(); - GetMeta(*heap, metaData); - - TSTSLAB_DBG(PrintMeta("after init allocs", metaData)); - TSTSLAB_DBG(DebugPrintSlabs(slabsetIndex, metaData)); - - //Check the number of pages used corresponds to the number of slabs. - TSTSLAB_DBG(RDebug::Printf("=========== Check the number of pages used corresponds to the number of slabs")); - - TInt pageCountForSlabs1 = (metaData.iChunkSize / PageSize) - 1; - TInt pageCountForSlabs2 = (initSlabCount+(slabsPerPage-1)) / slabsPerPage; - TSTSLAB_DBG(RDebug::Printf("=========== page counts: %d %d", pageCountForSlabs1, pageCountForSlabs2)); - test(pageCountForSlabs1 == pageCountForSlabs2); - - //----------------------------------------- - TSTSLAB_DBG(RDebug::Printf("=========== check slab counts in the lists")); - - slab* fullSlab = metaData.iFullSlab; - TInt fullSlabCount = 0; - while (fullSlab) - { - TSTSLAB_DBG(RDebug::Printf("fullSlab: 0x%08x", fullSlab)); - fullSlabCount++; - fullSlab = fullSlab->iChild1; - } - - TInt outParm; - TInt partialTreeSlabCount = 0; - partialTreeSlabCount = WalkSlabSet(slabsetIndex, metaData, ETestWalk, 0, outParm); - - slab* partialPageSlab = metaData.iPartialPage; - TInt partialPageSlabCount = 0; - while (partialPageSlab) - { - TSTSLAB_DBG(RDebug::Printf("partialPageSlab (empty): 0x%08x", partialPageSlab)); - partialPageSlabCount++; - partialPageSlab = partialPageSlab->iChild1; - } - - test(fullSlabCount == (initSlabCount-1)); - test(partialTreeSlabCount == 1); - if (initSlabCount % slabsPerPage == 0) - { - test(partialPageSlabCount == 0); - } - else - { - test(partialPageSlabCount == 1); - } - //----------------------------------------- - TSTSLAB_DBG(RDebug::Printf("=========== alloc one cell more -> one full slab more")); - - TAny* p = heap->Alloc(allocSize); - test(p != 0); - - heap->Check(); - GetMeta(*heap, metaData); - TSTSLAB_DBG(DebugPrintSlabs(slabsetIndex, metaData)); - - fullSlab = metaData.iFullSlab; - fullSlabCount = 0; - while (fullSlab) - { - TSTSLAB_DBG(RDebug::Printf("fullSlab: 0x%08x", fullSlab)); - fullSlabCount++; - fullSlab = fullSlab->iChild1; - } - test(fullSlabCount == initSlabCount); - - heap->Free(p); - - heap->Check(); - GetMeta(*heap, metaData); - TSTSLAB_DBG(DebugPrintSlabs(slabsetIndex, metaData)); - - //----------------------------------------- - //Check that a new slab is taken from a partially filled page if available. - TSTSLAB_DBG(RDebug::Printf("=========== Check that a new slab is taken from a partially filled page if available")); - - // fill the first slab in the page (after iSparePage) - TInt maxI5 = initCellCount + (cellCountPerSlab*(slabsPerPage+1)); - for (i=initCellCount; iAlloc(allocSize); - test(pBuf[i] != 0); - } - - heap->Check(); - GetMeta(*heap, metaData); - TSTSLAB_DBG(DebugPrintSlabs(slabsetIndex, metaData)); - - partialPageSlab = metaData.iPartialPage; - partialPageSlabCount = 0; - while (partialPageSlab) - { - TSTSLAB_DBG(RDebug::Printf("partialPageSlab (empty): 0x%08x", partialPageSlab)); - partialPageSlabCount++; - partialPageSlab = partialPageSlab->iChild1; - } - test(partialPageSlabCount == 1); - - page* page1 = PageFor(metaData.iPartialPage); - unsigned header = page1->iSlabs[0].iHeader; - unsigned pagemap = SlabHeaderPagemap(header); - unsigned slabix = LOWBIT(pagemap); - slab* partialPageSlab2 = &page1->iSlabs[slabix]; - - TAny* p2 = heap->Alloc(allocSize); - test(p2 != 0); - - heap->Check(); - TSTSLAB_DBG(RDebug::Printf("p2: 0x%08x; partialPageSlab2: 0x%08x", p2, partialPageSlab2)); - test(partialPageSlab2 == SlabFor(p2)); - heap->Free(p2); - - heap->Check(); - - //----------------------------- - // use the second page for the next test - TInt page2pBufIndexFirst = cellCountPerSlab * slabsPerPage; - //TInt page2pBufIndexLast = page2pBufIndexFirst + (cellCountPerSlab * slabsPerPage); - - //----------------------------------------- - //Check that a partially filled slab is used if available. - TSTSLAB_DBG(RDebug::Printf("=========== Check that a partially filled slab is used if available")); - - slab* partialTreeSlabX1 = SlabFor(pBuf[page2pBufIndexFirst]); - page* partialTreeSlabPageX1 = PageFor(partialTreeSlabX1); - - heap->Free(pBuf[page2pBufIndexFirst]); - pBuf[page2pBufIndexFirst] = 0; - - heap->Check(); - - TAny* p3 = heap->Alloc(allocSize); - test(p3 != 0); - heap->Check(); - test(partialTreeSlabX1 == SlabFor(p3)); - heap->Free(p3); - heap->Check(); - - //----------------------------------------- - //Check that if all four slabs in a page are free the page is freed. - TSTSLAB_DBG(RDebug::Printf("=========== Check that if all four slabs in a page are free, the page is freed")); - - GetMeta(*heap, metaData); - TSTSLAB_DBG(DebugPrintSlabs(slabsetIndex, metaData)); - - TInt size2 = metaData.iChunkSize; - TSTSLAB_DBG(RDebug::Printf("---- size2: 0x%08x", size2)); - if (metaData.iSparePage) - { - size2 -= PageSize; - } - - for (i=0; iFree(pBuf[i]); - pBuf[i] = 0; - } - } - } - - heap->Check(); - GetMeta(*heap, metaData); - TSTSLAB_DBG(DebugPrintSlabs(slabsetIndex, metaData)); - - TInt size3 = metaData.iChunkSize; - if (metaData.iSparePage) - { - size3 -= PageSize; - } - - test(size3 == (size2-PageSize)); - - //----------------------------------------- - //Free cells to give empty slab (The second slab in the first page) - TSTSLAB_DBG(RDebug::Printf("=========== Free cells to give empty slab (The second slab in the first page)")); - slab* emptySlabAddr = (slab*)(metaData.iMemBase + SLABSIZE); - - //Check that emptySlabAddr is not already in iPartialPage list - partialPageSlab = metaData.iPartialPage; - while (partialPageSlab) - { - if (partialPageSlab == emptySlabAddr) - { - test(0); - } - partialPageSlab = partialPageSlab->iChild1; - } - - // free cells to give empty slab - emptySlabAddr - TInt bufIndexFirst = cellCountPerSlab; - TInt maxI = bufIndexFirst + cellCountPerSlab; - for (i=bufIndexFirst; i<=maxI; ++i) - { - if (pBuf[i]) - { - heap->Free(pBuf[i]); - pBuf[i] = 0; - } - } - - heap->Check(); - GetMeta(*heap, metaData); - TSTSLAB_DBG(DebugPrintSlabs(slabsetIndex, metaData)); - - // Check that emptySlabAddr is not now in iPartialPage list - partialPageSlab = metaData.iPartialPage; - while (partialPageSlab) - { - if (partialPageSlab == emptySlabAddr) - { - break; - } - partialPageSlab = partialPageSlab->iChild1; - } - test(partialPageSlab != 0); - - //Free cells to give partial slab (The third slab in the first page) - TSTSLAB_DBG(RDebug::Printf("=========== Free cells to give partial slab (The third slab in the first page)")); - slab* partialSlabAddr = (slab*)(metaData.iMemBase + (3*SLABSIZE)); - - // Check that partialSlabAddr is not now in iPartialSlab list - WalkSlabSet(slabsetIndex, metaData, ETestFindSlab, partialSlabAddr, outParm); - test(outParm == 0); - - TInt firstI = cellCountPerSlab * 3; - maxI = firstI + cellCountPerSlab; - for (i=firstI; i<=maxI; ++i) - { - if (i % 3 == 0) - { - if (pBuf[i]) - { - heap->Free(pBuf[i]); - pBuf[i] = 0; - } - } - } - - heap->Check(); - GetMeta(*heap, metaData); - TSTSLAB_DBG(DebugPrintSlabs(slabsetIndex, metaData)); - - // Check that partialSlabAddr is now in iPartialSlab list - WalkSlabSet(slabsetIndex, metaData, ETestFindSlab, partialSlabAddr, outParm); - test(outParm == 1); - - //Reallocate cells. - for (i=0; i<(MAX_ALLOCS); ++i) - { - if (pBuf[i] != 0) - { - pBuf[i] = heap->ReAlloc(pBuf[i], allocSize); - test(pBuf[i] != 0); - } - } - - heap->Check(); - - //Allocate cells. - for (i=0; i<(MAX_ALLOCS/4); ++i) - { - if (pBuf[i] == 0) - { - pBuf[i] = heap->Alloc(allocSize); - test(pBuf[i] != 0); - } - } - - heap->Check(); - - for (i=0; iFree(pBuf[i]); - pBuf[i] = 0; - } - } - heap->Check(); - - TSTSLAB_DBG(RDebug::Printf("=========== TestSlabFixedSizeOneThread end")); - } - -LOCAL_C RHeap* CreateSlabHeap(TInt aThreadCount) -{ - //TPtrC slabHeap=_L("SlabHeap"); - //RHeap* heap = User::ChunkHeap(&slabHeap, 0x1000, 0x10000); - TInt maxLth = 0x60000 * aThreadCount; - RHeap* heap = User::ChunkHeap(0, 0x1000, maxLth); - test(heap!=NULL); - - // Configure heap for slab - RHybridHeap::STestCommand cmd; - cmd.iCommand = RHybridHeap::ESetConfig; - cmd.iConfig.iSlabBits = 0xabe; - cmd.iConfig.iDelayedSlabThreshold = 0; - cmd.iConfig.iPagePower = 0; // 16 // 0 -> no page allocator - TInt ret = heap->DebugFunction(RHeap::EHybridHeap, &cmd, 0); - test(ret == KErrNone); - - return heap; -} - -LOCAL_C TInt SlabTestManyThreads(TAny* aThreadParm) - { - TSlabTestThreadParm* parm = (TSlabTestThreadParm*)aThreadParm; - - TInt i; - TInt maxLoops = 30; //300; - for (i=0; i threadName; - threadName.Format(_L("SlabTest%d"), index); - if (aThreadCount == 1) - { - ret = theThreads[index].Create(threadName, SlabTestOneThread, KSlabTestThreadStackSize, NULL, (TAny*)&ThreadParm[index]); - } - else - { - ret = theThreads[index].Create(threadName, SlabTestManyThreads, KSlabTestThreadStackSize, NULL, (TAny*)&ThreadParm[index]); - } - test(ret == KErrNone); - theThreads[index].Logon(theStatus[index]); - test(theStatus[index] == KRequestPending); - threadInUse[index] = ETrue; - theThreads[index].Resume(); - } - - User::WaitForAnyRequest(); - - TBool anyUsed = ETrue; - while (anyUsed) - { - User::After(1001000); - anyUsed = EFalse; - for (index = 0; index < aThreadCount; index++) - { - if (threadInUse[index]) - { - if (theThreads[index].ExitType() != EExitPending) - { - threadInUse[index] = EFalse; - } - else - { - anyUsed = ETrue; - } - } - } - } - - for (index = 0; index < aThreadCount; index++) - { - theThreads[index].Close(); - } - TSTSLAB_DBG(RDebug::Printf("=========== StartThreads end")); - heap->Close(); - - return KErrNone; - } - -GLDEF_C TInt E32Main(void) - { - TInt ret; - - test.Title(); - - __KHEAP_MARK; - - test.Start(_L("TestSlab")); - UserHal::PageSizeInBytes(PageSize); - - RHeap* heap = CreateSlabHeap(1); - - TMetaData metaData; - GetMeta(*heap, metaData); - - heap->Close(); - - if (metaData.iDLOnly) - { - test.Printf(_L("Slab allocator is not used, no tests to run\n")); - __KHEAP_MARKEND; - test.End(); - return(0); - } - - TSlabTestThreadParm threadParm; - threadParm.iHeap = heap; - threadParm.iAllocSize = 17; - threadParm.iInitSlabCount = 128; // 12 - threadParm.iUseRandomSize = EFalse; - - test.Next(_L("TestSlab - one thread")); - - TInt threadCount; - threadCount = 1; - if (threadCount > MAX_THREADS) - { - threadCount = MAX_THREADS; - } - threadParm.iThreadCount = threadCount; - -#if 0 - ret = StartThreads(threadCount, threadParm); - test(ret==KErrNone); - -#else - - TInt i; - for (i=1; i= metaData.iSlabThreshold) - { - break; - } -#endif // _DEBUG - TSTSLAB_DBG(RDebug::Printf("=========== StartThreads size: %d", i)); - threadParm.iAllocSize = i; - test.Printf(_L("AllocSize: %d\n"), i); - ret = StartThreads(threadCount, threadParm); - test(ret==KErrNone); - } -#endif - - - test.Next(_L("TestSlab - many threads")); - - threadParm.iAllocSize = 17; - - threadCount = 3; - if (threadCount > MAX_THREADS) - { - threadCount = MAX_THREADS; - } - threadParm.iThreadCount = threadCount; - -#if 1 - ret = StartThreads(threadCount, threadParm); - test(ret==KErrNone); - -#else - - TInt i; - for (i=1; i= metaData.iSlabThreshold) - { - break; - } -#endif // _DEBUG - TSTSLAB_DBG(RDebug::Printf("=========== StartThreads size: %d", i)); - threadParm.iAllocSize = i; - test.Printf(_L("AllocSize: %d\n"), i); - ret = StartThreads(threadCount, threadParm); - test(ret==KErrNone); - } -#endif - - __KHEAP_MARKEND; - - test.End(); - return(0); - }