VirtualBox

Changeset 22273 in vbox for trunk/src/VBox/Runtime/testcase


Ignore:
Timestamp:
Aug 14, 2009 11:00:51 PM (15 years ago)
Author:
vboxsync
Message:

IPRT: Added RTHeapSimpleRelocate for saving and restoring of the heap.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/testcase/tstHeapSimple.cpp

    r21292 r22273  
    1 /* $Id $ */
     1/* $Id$ */
    22/** @file
    33 * IPRT Testcase - Simple Heap.
     
    4040#include <iprt/assert.h>
    4141#include <iprt/log.h>
     42#include <iprt/test.h>
    4243
    4344
     
    4748     * Init runtime.
    4849     */
    49     int rc = RTR3Init();
    50     if (RT_FAILURE(rc))
    51     {
    52         RTPrintf("RTR3Init failed: %Rrc\n", rc);
    53         return 1;
    54     }
    55     RTPrintf("tstHeapSimple: TESTING...\n");
     50    RTTEST hTest;
     51    int rc = RTTestInitAndCreate("tstRTHeapSimple", &hTest);
     52    if (rc)
     53        return rc;
     54    RTTestBanner(hTest);
    5655
    5756    /*
    5857     * Create a heap.
    5958     */
     59    RTTestSub(hTest, "Basics");
    6060    static uint8_t s_abMem[128*1024];
    6161    RTHEAPSIMPLE Heap;
    62     rc = RTHeapSimpleInit(&Heap, &s_abMem[1], sizeof(s_abMem) - 1);
    63     if (RT_FAILURE(rc))
    64     {
    65         RTPrintf("RTHeapSimpleInit failed: %Rrc\n", rc);
    66         return 1;
    67     }
     62    RTTESTI_CHECK_RC(rc = RTHeapSimpleInit(&Heap, &s_abMem[1], sizeof(s_abMem) - 1), VINF_SUCCESS);
     63    if (RT_FAILURE(rc))
     64        return RTTestSummaryAndDestroy(hTest);
    6865
    6966    /*
    7067     * Try allocate.
    7168     */
    72     static struct
     69    static struct TstHeapSimpleOps
    7370    {
    7471        size_t      cb;
     
    7673        void       *pvAlloc;
    7774        unsigned    iFreeOrder;
    78     } aOps[] =
     75    } s_aOps[] =
    7976    {
    8077        {        16,          0,    NULL,  0 },  // 0
     
    10198        {        16,          0,    NULL,  7 },
    10299    };
    103     unsigned i;
    104     RTHeapSimpleDump(Heap, (PFNRTHEAPSIMPLEPRINTF)RTPrintf);
     100    unsigned i;                                   
     101    RTHeapSimpleDump(Heap, (PFNRTHEAPSIMPLEPRINTF)RTPrintf); /** @todo Add some detail info output with a signature identical to RTPrintf. */
    105102    size_t cbBefore = RTHeapSimpleGetFreeSize(Heap);
    106103    static char szFill[] = "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    107104
    108105    /* allocate */
    109     for (i = 0; i < RT_ELEMENTS(aOps); i++)
    110     {
    111         aOps[i].pvAlloc = RTHeapSimpleAlloc(Heap, aOps[i].cb, aOps[i].uAlignment);
    112         if (!aOps[i].pvAlloc)
    113         {
    114             RTPrintf("Failure: RTHeapSimpleAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, aOps[i].cb, aOps[i].uAlignment, i);
    115             return 1;
    116         }
    117         memset(aOps[i].pvAlloc, szFill[i], aOps[i].cb);
    118         if (RT_ALIGN_P(aOps[i].pvAlloc, (aOps[i].uAlignment ? aOps[i].uAlignment : 8)) != aOps[i].pvAlloc)
    119         {
    120             RTPrintf("Failure: RTHeapSimpleAlloc(%p, %#x, %#x,) -> %p\n", (void *)Heap, aOps[i].cb, aOps[i].uAlignment, i);
    121             return 1;
    122         }
     106    for (i = 0; i < RT_ELEMENTS(s_aOps); i++)
     107    {
     108        s_aOps[i].pvAlloc = RTHeapSimpleAlloc(Heap, s_aOps[i].cb, s_aOps[i].uAlignment);
     109        RTTESTI_CHECK_MSG(s_aOps[i].pvAlloc, ("RTHeapSimpleAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i));
     110        if (!s_aOps[i].pvAlloc)
     111            return RTTestSummaryAndDestroy(hTest);
     112
     113        memset(s_aOps[i].pvAlloc, szFill[i], s_aOps[i].cb);
     114        RTTESTI_CHECK_MSG(RT_ALIGN_P(s_aOps[i].pvAlloc, (s_aOps[i].uAlignment ? s_aOps[i].uAlignment : 8)) == s_aOps[i].pvAlloc,
     115                          ("RTHeapSimpleAlloc(%p, %#x, %#x,) -> %p\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i));
     116        if (!s_aOps[i].pvAlloc)
     117            return RTTestSummaryAndDestroy(hTest);
    123118    }
    124119
    125120    /* free and allocate the same node again. */
    126     for (i = 0; i < RT_ELEMENTS(aOps); i++)
    127     {
    128         if (!aOps[i].pvAlloc)
     121    for (i = 0; i < RT_ELEMENTS(s_aOps); i++)
     122    {
     123        if (!s_aOps[i].pvAlloc)
    129124            continue;
    130         //RTPrintf("debug: i=%d pv=%#x cb=%#zx align=%#zx cbReal=%#zx\n", i, aOps[i].pvAlloc,
    131         //         aOps[i].cb, aOps[i].uAlignment, RTHeapSimpleSize(Heap, aOps[i].pvAlloc));
     125        //RTPrintf("debug: i=%d pv=%#x cb=%#zx align=%#zx cbReal=%#zx\n", i, s_aOps[i].pvAlloc,
     126        //         s_aOps[i].cb, s_aOps[i].uAlignment, RTHeapSimpleSize(Heap, s_aOps[i].pvAlloc));
    132127        size_t cbBeforeSub = RTHeapSimpleGetFreeSize(Heap);
    133         RTHeapSimpleFree(Heap, aOps[i].pvAlloc);
     128        RTHeapSimpleFree(Heap, s_aOps[i].pvAlloc);
    134129        size_t cbAfterSubFree = RTHeapSimpleGetFreeSize(Heap);
    135130
    136131        void *pv;
    137         pv = RTHeapSimpleAlloc(Heap, aOps[i].cb, aOps[i].uAlignment);
     132        pv = RTHeapSimpleAlloc(Heap, s_aOps[i].cb, s_aOps[i].uAlignment);
     133        RTTESTI_CHECK_MSG(pv, ("RTHeapSimpleAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i));
    138134        if (!pv)
    139         {
    140             RTPrintf("Failure: RTHeapSimpleAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, aOps[i].cb, aOps[i].uAlignment, i);
    141             return 1;
    142         }
     135            return RTTestSummaryAndDestroy(hTest);
    143136        //RTPrintf("debug: i=%d pv=%p cbReal=%#zx cbBeforeSub=%#zx cbAfterSubFree=%#zx cbAfterSubAlloc=%#zx \n", i, pv, RTHeapSimpleSize(Heap, pv),
    144137        //         cbBeforeSub, cbAfterSubFree, RTHeapSimpleGetFreeSize(Heap));
    145         if (pv != aOps[i].pvAlloc)
    146             RTPrintf("Warning: Free+Alloc returned different address. new=%p old=%p i=%d\n", pv, aOps[i].pvAlloc, i);
    147         aOps[i].pvAlloc = pv;
     138        if (pv != s_aOps[i].pvAlloc)
     139            RTTestIPrintf(RTTESTLVL_ALWAYS, "Warning: Free+Alloc returned different address. new=%p old=%p i=%d\n", pv, s_aOps[i].pvAlloc, i);
     140        s_aOps[i].pvAlloc = pv;
    148141        size_t cbAfterSubAlloc = RTHeapSimpleGetFreeSize(Heap);
    149142        if (cbBeforeSub != cbAfterSubAlloc)
    150143        {
    151             RTPrintf("Warning: cbBeforeSub=%#zx cbAfterSubFree=%#zx cbAfterSubAlloc=%#zx. i=%d\n",
    152                      cbBeforeSub, cbAfterSubFree, cbAfterSubAlloc, i);
     144            RTTestIPrintf(RTTESTLVL_ALWAYS, "Warning: cbBeforeSub=%#zx cbAfterSubFree=%#zx cbAfterSubAlloc=%#zx. i=%d\n",
     145                          cbBeforeSub, cbAfterSubFree, cbAfterSubAlloc, i);
    153146            //return 1; - won't work correctly until we start creating free block instead of donating memory on alignment.
    154147        }
    155148    }
     149   
     150    /* make a copy of the heap and the to-be-freed list. */
     151    static uint8_t s_abMemCopy[sizeof(s_abMem)];
     152    memcpy(s_abMemCopy, s_abMem, sizeof(s_abMem));
     153    uintptr_t    offDelta  = (uintptr_t)&s_abMemCopy[0] - (uintptr_t)&s_abMem[0];
     154    RTHEAPSIMPLE hHeapCopy = (RTHEAPSIMPLE)((uintptr_t)Heap + offDelta);
     155    static struct TstHeapSimpleOps s_aOpsCopy[RT_ELEMENTS(s_aOps)];
     156    memcpy(&s_aOpsCopy[0], &s_aOps[0], sizeof(s_aOps));
    156157
    157158    /* free it in a specific order. */
    158159    int cFreed = 0;
    159     for (i = 0; i < RT_ELEMENTS(aOps); i++)
     160    for (i = 0; i < RT_ELEMENTS(s_aOps); i++)
    160161    {
    161162        unsigned j;
    162         for (j = 0; j < RT_ELEMENTS(aOps); j++)
     163        for (j = 0; j < RT_ELEMENTS(s_aOps); j++)
    163164        {
    164             if (    aOps[j].iFreeOrder != i
    165                 ||  !aOps[j].pvAlloc)
     165            if (    s_aOps[j].iFreeOrder != i
     166                ||  !s_aOps[j].pvAlloc)
    166167                continue;
    167             //RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, RTHeapSimpleGetFreeSize(Heap), aOps[j].cb, aOps[j].pvAlloc);
    168             RTHeapSimpleFree(Heap, aOps[j].pvAlloc);
    169             aOps[j].pvAlloc = NULL;
     168            //RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, RTHeapSimpleGetFreeSize(Heap), s_aOps[j].cb, s_aOps[j].pvAlloc);
     169            RTHeapSimpleFree(Heap, s_aOps[j].pvAlloc);
     170            s_aOps[j].pvAlloc = NULL;
    170171            cFreed++;
    171172        }
    172173    }
    173     Assert(cFreed == RT_ELEMENTS(aOps));
    174     RTPrintf("i=done free=%d\n", RTHeapSimpleGetFreeSize(Heap));
     174    RTTESTI_CHECK(cFreed == RT_ELEMENTS(s_aOps));
     175    RTTestIPrintf(RTTESTLVL_ALWAYS, "i=done free=%d\n", RTHeapSimpleGetFreeSize(Heap));
    175176
    176177    /* check that we're back at the right amount of free memory. */
     
    178179    if (cbBefore != cbAfter)
    179180    {
    180         RTPrintf("Warning: Either we've split out an alignment chunk at the start, or we've got\n"
    181                  "         an alloc/free accounting bug: cbBefore=%d cbAfter=%d\n", cbBefore, cbAfter);
     181        RTTestIPrintf(RTTESTLVL_ALWAYS,
     182                      "Warning: Either we've split out an alignment chunk at the start, or we've got\n"
     183                      "         an alloc/free accounting bug: cbBefore=%d cbAfter=%d\n", cbBefore, cbAfter);
    182184        RTHeapSimpleDump(Heap, (PFNRTHEAPSIMPLEPRINTF)RTPrintf);
    183185    }
    184186
    185     RTPrintf("tstHeapSimple: Success\n");
    186 #ifdef LOG_ENABLED
    187     RTLogFlush(NULL);
    188 #endif
    189     return 0;
     187    /* relocate and free the bits in heap2 now. */
     188    RTTestSub(hTest, "RTHeapSimpleRelocate");
     189    rc = RTHeapSimpleRelocate(hHeapCopy, offDelta);
     190    RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
     191    if (RT_FAILURE(rc))
     192    {
     193        /* free it in a specific order. */
     194        int cFreed2 = 0;
     195        for (i = 0; i < RT_ELEMENTS(s_aOpsCopy); i++)
     196        {
     197            unsigned j;
     198            for (j = 0; j < RT_ELEMENTS(s_aOpsCopy); j++)
     199            {
     200                if (    s_aOpsCopy[j].iFreeOrder != i
     201                    ||  !s_aOpsCopy[j].pvAlloc)
     202                    continue;
     203                //RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, RTHeapSimpleGetFreeSize(hHeapCopy), s_aOpsCopy[j].cb, s_aOpsCopy[j].pvAlloc);
     204                RTHeapSimpleFree(hHeapCopy, (uint8_t *)s_aOpsCopy[j].pvAlloc + offDelta);
     205                s_aOpsCopy[j].pvAlloc = NULL;
     206                cFreed++;
     207            }
     208        }
     209        RTTESTI_CHECK(cFreed == RT_ELEMENTS(s_aOpsCopy));
     210   
     211        /* check that we're back at the right amount of free memory. */
     212        size_t cbAfterCopy = RTHeapSimpleGetFreeSize(hHeapCopy);
     213        RTTESTI_CHECK_MSG(cbAfterCopy == cbAfter, ("cbAfterCopy=%zu cbAfter=%zu\n", cbAfterCopy, cbAfter));
     214    }
     215
     216
     217    return RTTestSummaryAndDestroy(hTest);
    190218}
     219
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette