kerneltest/e32test/heap/t_heapslab.cpp
branchRCL_3
changeset 44 3e88ff8f41d5
parent 43 c1f20ce4abcf
child 45 9e2d4f7f5028
--- 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 <e32test.h>
-#include <e32hal.h>
-#include <e32def.h>
-#include <e32def_private.h>
-#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; 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);
-}
-
-/*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<count; ++i)
-        {
-        RDebug::Printf("iSizeMap[%d]: %d", i, aMeta.iSizeMap[i]);
-        }
-    count = sizeof(aMeta.iSlabAlloc)/sizeof(slabset);
-    for (i=0; i<count; ++i)
-        {
-        RDebug::Printf("iSlabAlloc[%d].iPartial: 0x%08x", i, aMeta.iSlabAlloc[i].iPartial);
-        }
-    for (i=0; i<count; ++i)
-        {
-        RDebug::Printf("iSlabAllocRealRootAddress[%d]: 0x%08x", i, aMeta.iSlabAllocRealRootAddress[i]);
-        }
-    RDebug::Printf("=========== HeapMetaData (local) - end");
-}
-
-LOCAL_C void GetAndPrintMeta(RHeap& aHeap, const char* aText, TMetaData& aMeta)
-{
-    (void)aText;
-    GetMeta(aHeap, aMeta);
-    TSTSLAB_DBG(PrintMeta(aText, aMeta));
-}
-
-#ifndef __KERNEL_MODE__
-LOCAL_C void Lock(TMetaData& aMeta)
-   {((RFastLock&)*aMeta.iLock).Wait();}
-
-LOCAL_C void Unlock(TMetaData& aMeta)
-   {((RFastLock&)*aMeta.iLock).Signal();}
-#else
-LOCAL_C void Lock(TMetaData& aMeta)
-   {;}
-
-LOCAL_C void Unlock(TMetaData& aMeta)
-   {;}
-#endif
-*/
-
-LOCAL_C  page* PageFor(slab* s)
-    {
-        return reinterpret_cast<page*>(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<MAX_ALLOCS; ++i)
-        {
-        pBuf[i] = 0;
-        }
-
-    //Allocate enough cells of the same size to fill initSlabCount (128) slabs
-    TInt slabsetIndex = metaData.iSizeMap[(allocRealCellSize+3)>>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; i<initCellCount; ++i)
-        {
-        pBuf[i] = heap->Alloc(allocSize);
-        test(pBuf[i] != 0);
-        }
-
-    heap->Check();
-
-    TInt maxI5 = initCellCount + (cellCountPerSlab*(slabsPerPage+1));
-    for (i=initCellCount; i<maxI5; ++i)
-        {
-        pBuf[i] = heap->Alloc(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; i<MAX_ALLOCS; ++i)
-        {
-        if (pBuf[i]) {
-            page* page1 = PageFor(SlabFor(pBuf[i]));
-            if (partialTreeSlabPageX1 == page1)
-                {
-                heap->Free(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; i<MAX_ALLOCS; ++i)
-        {
-        if (pBuf[i])
-            {
-            heap->Free(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<MAX_ALLOCS; ++i)
-        {
-        pBuf[i] = 0;
-        }
-
-    //Allocate enough cells of the same size to fill initSlabCount (128) slabs
-    TInt slabsetIndex = metaData.iSizeMap[(allocRealCellSize+3)>>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; i<initCellCount; ++i)
-        {
-        pBuf[i] = heap->Alloc(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; i<maxI5; ++i)
-        {
-        pBuf[i] = heap->Alloc(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; i<MAX_ALLOCS; ++i)
-        {
-        if (pBuf[i]) {
-            page* page1 = PageFor(SlabFor(pBuf[i]));
-            if (partialTreeSlabPageX1 == page1)
-                {
-                heap->Free(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; i<MAX_ALLOCS; ++i)
-        {
-        if (pBuf[i])
-            {
-            heap->Free(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<maxLoops; ++i)
-        {
-        TestSlabFixedSizeManyThreads(*parm);
-        }
-                                
-    return KErrNone;
-    }
-    
-LOCAL_C TInt SlabTestOneThread(TAny* aThreadParm)
-    {
-    TSlabTestThreadParm* parm = (TSlabTestThreadParm*)aThreadParm;
-    TestSlabFixedSizeOneThread(*parm);
-    return KErrNone;
-    }
-    
-TInt StartThreads(TInt aThreadCount, TSlabTestThreadParm& aThreadParm)
-    {
-    const TInt KSlabTestThreadStackSize=0x4000; //0x10000; //0x2000;
-
-    TRequestStatus  theStatus[MAX_THREADS];
-    RThread         theThreads[MAX_THREADS];
-    TBool           threadInUse[MAX_THREADS];
-
-    TInt index;
-    TInt ret;
-
-    if (aThreadCount <= 0)
-        {
-        return KErrNone;
-        }
-
-    RHeap* heap = CreateSlabHeap(aThreadCount);
-    aThreadParm.iHeap = heap;
-    
-    for (index = 0; index < aThreadCount; index++)
-        {
-        ThreadParm[index].iHeap             = aThreadParm.iHeap;
-        ThreadParm[index].iAllocSize        = aThreadParm.iAllocSize;
-        ThreadParm[index].iInitSlabCount    = aThreadParm.iInitSlabCount;
-        ThreadParm[index].iUseRandomSize    = aThreadParm.iUseRandomSize;
-        ThreadParm[index].iThreadCount      = aThreadParm.iThreadCount;
-        
-        ThreadParm[index].iThreadIndex = index;
-        
-        TBuf<32> 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; ++i)
-        {
-#ifdef _DEBUG
-        if ((i + RHeap::EDebugHdrSize) >= 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; ++i)
-        {
-#ifdef _DEBUG
-        if ((i + RHeap::EDebugHdrSize) >= 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);
-    }