VirtualBox

Changeset 288

Show
Ignore:
Timestamp:
01/25/07 06:14:15 (2 years ago)
Author:
vboxsync
Message:

debugged the heap.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/iprt/heap.h

    r283 r288  
    3333/** Pointer to a handle to a simple heap. */ 
    3434typedef RTHEAPSIMPLE *PRTHEAPSIMPLE; 
     35 
     36/** NIL simple heap handle. */ 
     37#define NIL_RTHEAPSIMPLE    ((RTHEAPSIMPLE)0) 
    3538/* <<< types.h */ 
    3639 
     
    3942/** 
    4043 * Initializes the heap. 
    41  *  
     44 * 
    4245 * @returns IPRT status code on success. 
    4346 * @param   pHeap       Where to store the heap anchor block on success. 
     
    4952/** 
    5053 * Merge two simple heaps into one. 
    51  *  
     54 * 
    5255 * The requiremet is of course that they next two each other memory wise. 
    53  *  
     56 * 
    5457 * @returns IPRT status code on success. 
    5558 * @param   pHeap       Where to store the handle to the merged heap on success. 
    5659 * @param   Heap1       Handle to the first heap. 
    5760 * @param   Heap2       Handle to the second heap. 
     61 * @remark  This API isn't implemented yet. 
    5862 */ 
    5963RTDECL(int) RTHeapSimpleMerge(PRTHEAPSIMPLE pHeap, RTHEAPSIMPLE Heap1, RTHEAPSIMPLE Heap2); 
     
    6165/** 
    6266 * Allocates memory from the specified simple heap. 
    63  *  
     67 * 
    6468 * @returns Pointer to the allocated memory block on success. 
    6569 * @returns NULL if the request cannot be satisfied. (A VERR_NO_MEMORY condition.) 
    66  *  
     70 * 
    6771 * @param   Heap        The heap to allocate the memory on. 
    6872 * @param   cb          The requested heap block size. 
     
    7478/** 
    7579 * Allocates zeroed memory from the specified simple heap. 
    76  *  
     80 * 
    7781 * @returns Pointer to the allocated memory block on success. 
    7882 * @returns NULL if the request cannot be satisfied. (A VERR_NO_MEMORY condition.) 
    79  *  
     83 * 
    8084 * @param   Heap        The heap to allocate the memory on. 
    8185 * @param   cb          The requested heap block size. 
     
    8690 
    8791/** 
     92 * Reallocates / Allocates / Frees a heap block. 
     93 * 
     94 * @param   Heap        The heap. This is optional and will only be used for strict assertions. 
     95 * @param   pv          The heap block returned by RTHeapSimple. If NULL it behaves like RTHeapSimpleAlloc(). 
     96 * @param   cbNew       The new size of the heap block. If NULL it behaves like RTHeapSimpleFree(). 
     97 * @param   cbAlignment The requested heap block alignment. Pass 0 for default alignment. 
     98 *                      Must be a power of 2. 
     99 * @remark  This API isn't implemented yet. 
     100 */ 
     101RTDECL(void *) RTHeapSimpleRealloc(RTHEAPSIMPLE Heap, void *pv, size_t cbNew, size_t cbAlignment); 
     102 
     103/** 
     104 * Reallocates / Allocates / Frees a heap block, zeroing any new bits. 
     105 * 
     106 * @param   Heap        The heap. This is optional and will only be used for strict assertions. 
     107 * @param   pv          The heap block returned by RTHeapSimple. If NULL it behaves like RTHeapSimpleAllocZ(). 
     108 * @param   cbNew       The new size of the heap block. If NULL it behaves like RTHeapSimpleFree(). 
     109 * @param   cbAlignment The requested heap block alignment. Pass 0 for default alignment. 
     110 *                      Must be a power of 2. 
     111 * @remark  This API isn't implemented yet. 
     112 */ 
     113RTDECL(void *) RTHeapSimpleReallocZ(RTHEAPSIMPLE Heap, void *pv, size_t cbNew, size_t cbAlignment); 
     114 
     115/** 
    88116 * Frees memory allocated from a simple heap. 
    89  *  
     117 * 
    90118 * @param   Heap    The heap. This is optional and will only be used for strict assertions. 
    91119 * @param   pv      The heap block returned by RTHeapSimple 
     
    93121RTDECL(void) RTHeapSimpleFree(RTHEAPSIMPLE Heap, void *pv); 
    94122 
    95 #ifdef DEBUG 
    96123/** 
    97  * Dumps the hypervisor heap to the (default) log. 
    98  *  
     124 * Gets the size of the specified heap block. 
     125 * 
     126 * @returns The actual size of the heap block. 
     127 * @returns 0 if \a pv is NULL or it doesn't point to a valid heap block. An invalid \a pv 
     128 *          can also cause traps or trigger assertions. 
     129 * @param   Heap    The heap. This is optional and will only be used for strict assertions. 
     130 * @param   pv      The heap block returned by RTHeapSimple 
     131 */ 
     132RTDECL(size_t) RTHeapSimpleSize(RTHEAPSIMPLE Heap, void *pv); 
     133 
     134/** 
     135 * Gets the size of the heap. 
     136 * 
     137 * This size includes all the internal heap structures. So, even if the heap is 
     138 * empty the RTHeapSimpleGetFreeSize() will never reach the heap size returned 
     139 * by this function. 
     140 * 
     141 * @returns The heap size. 
     142 * @returns 0 if heap was safely detected as being bad. 
     143 * @param   Heap    The heap. 
     144 */ 
     145RTDECL(size_t) RTHeapSimpleGetHeapSize(RTHEAPSIMPLE Heap); 
     146 
     147/** 
     148 * Returns the sum of all free heap blocks. 
     149 * 
     150 * This is the amount of memory you can theoretically allocate 
     151 * if you do allocations exactly matching the free blocks. 
     152 * 
     153 * @returns The size of the free blocks. 
     154 * @returns 0 if heap was safely detected as being bad. 
     155 * @param   Heap    The heap. 
     156 */ 
     157RTDECL(size_t) RTHeapSimpleGetFreeSize(RTHEAPSIMPLE Heap); 
     158 
     159/** 
     160 * Printf like callbaclk function for RTHeapSimpleDump. 
     161 * @param   pszFormat   IPRT format string. 
     162 * @param   ...         Format arguments. 
     163 */ 
     164typedef DECLCALLBACK(void) FNRTHEAPSIMPLEPRINTF(const char *pszFormat, ...); 
     165/** Pointer to a FNRTHEAPSIMPLEPRINTF function. */ 
     166typedef FNRTHEAPSIMPLEPRINTF *PFNRTHEAPSIMPLEPRINTF; 
     167 
     168/** 
     169 * Dumps the hypervisor heap. 
     170 * 
    99171 * @param   Heap        The heap handle. 
     172 * @param   pfnPrintf   Printf like function that groks IPRT formatting. 
    100173 */ 
    101 RTDECL(void) RTHeapSimpleDump(RTHEAPSIMPLE Heap); 
    102 #endif 
    103  
     174RTDECL(void) RTHeapSimpleDump(RTHEAPSIMPLE Heap, PFNRTHEAPSIMPLEPRINTF pfnPrintf); 
    104175 
    105176__END_DECLS 
    106177 
    107 #endif  
     178#endif 
    108179 
  • trunk/src/VBox/Runtime/testcase/tstHeapSimple.cpp

    r283 r288  
    6868    } aOps[] = 
    6969    { 
    70         {        16,          0,    NULL,  0 }, 
     70        {        16,          0,    NULL,  0 },  // 0 
    7171        {        16,          4,    NULL,  1 }, 
    7272        {        16,          8,    NULL,  2 }, 
    7373        {        16,         16,    NULL,  5 }, 
    7474        {        16,         32,    NULL,  4 }, 
    75         {        32,          0,    NULL,  3 }, 
     75        {        32,          0,    NULL,  3 },  // 5 
    7676        {        31,          0,    NULL,  6 }, 
    7777        {      1024,          0,    NULL,  8 }, 
    7878        {      1024,         32,    NULL, 10 }, 
    7979        {      1024,         32,    NULL, 12 }, 
    80         { PAGE_SIZE,  PAGE_SIZE,    NULL, 13 }, 
     80        { PAGE_SIZE,  PAGE_SIZE,    NULL, 13 },  // 10 
    8181        {      1024,         32,    NULL,  9 }, 
    8282        { PAGE_SIZE,         32,    NULL, 11 }, 
    8383        { PAGE_SIZE,  PAGE_SIZE,    NULL, 14 }, 
    8484        {        16,          0,    NULL, 15 }, 
    85         {        9,           0,    NULL,  7 }, 
     85        {        9,           0,    NULL,  7 },  // 15 
    8686        {        16,          0,    NULL,  7 }, 
    8787        {        36,          0,    NULL,  7 }, 
    8888        {        16,          0,    NULL,  7 }, 
    8989        {     12344,          0,    NULL,  7 }, 
    90         {        50,          0,    NULL,  7 }, 
     90        {        50,          0,    NULL,  7 },  // 20 
    9191        {        16,          0,    NULL,  7 }, 
    9292    }; 
    9393    unsigned i; 
    94 #ifdef DEBUG 
    95     RTHeapSimpleDump(Heap); 
    96 #endif 
    97 //    size_t cbBefore = RTHeapSimpleGetFreeSize(Heap); 
    98     size_t cbBefore = 0; 
     94    RTHeapSimpleDump(Heap, (PFNRTHEAPSIMPLEPRINTF)RTPrintf); 
     95    size_t cbBefore = RTHeapSimpleGetFreeSize(Heap); 
    9996    static char szFill[] = "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    10097 
     
    119116    for (i = 0; i < ELEMENTS(aOps); i++) 
    120117    { 
    121         if (    !aOps[i].pvAlloc 
    122             ||  aOps[i].uAlignment == PAGE_SIZE) 
     118        if (!aOps[i].pvAlloc) 
    123119            continue; 
    124         //size_t cbBeforeSub = RTHeapSimpleGetFreeSize(Heap); 
     120        //RTPrintf("debug: i=%d pv=%#x cb=%#zx align=%#zx cbReal=%#zx\n", i, aOps[i].pvAlloc, 
     121        //         aOps[i].cb, aOps[i].uAlignment, RTHeapSimpleSize(Heap, aOps[i].pvAlloc)); 
     122        size_t cbBeforeSub = RTHeapSimpleGetFreeSize(Heap); 
    125123        RTHeapSimpleFree(Heap, aOps[i].pvAlloc); 
     124        size_t cbAfterSubFree = RTHeapSimpleGetFreeSize(Heap); 
    126125 
    127         //RTPrintf("debug: i=%d cbBeforeSub=%d now=%d\n", i, cbBeforeSub, RTHeapSimpleGetFreeSize(Heap)); 
    128126        void *pv; 
    129127        pv = RTHeapSimpleAlloc(Heap, aOps[i].cb, aOps[i].uAlignment); 
    130         if (pv) 
     128        if (!pv) 
    131129        { 
    132130            RTPrintf("Failure: RTHeapSimpleAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, aOps[i].cb, aOps[i].uAlignment, i); 
    133131            return 1; 
    134132        } 
     133        //RTPrintf("debug: i=%d pv=%p cbReal=%#zx cbBeforeSub=%#zx cbAfterSubFree=%#zx cbAfterSubAlloc=%#zx \n", i, pv, RTHeapSimpleSize(Heap, pv), 
     134        //         cbBeforeSub, cbAfterSubFree, RTHeapSimpleGetFreeSize(Heap)); 
    135135        if (pv != aOps[i].pvAlloc) 
     136            RTPrintf("Warning: Free+Alloc returned different address. new=%p old=%p i=%d\n", pv, aOps[i].pvAlloc, i); 
     137        aOps[i].pvAlloc = pv; 
     138        size_t cbAfterSubAlloc = RTHeapSimpleGetFreeSize(Heap); 
     139        if (cbBeforeSub != cbAfterSubAlloc) 
    136140        { 
    137             RTPrintf("Failure: Free+Alloc returned different address. new=%p old=%p i=%d (doesn't work with delayed free)\n", pv, aOps[i].pvAlloc, i); 
    138             //return 1; 
     141            RTPrintf("Warning: cbBeforeSub=%#zx cbAfterSubFree=%#zx cbAfterSubAlloc=%#zx. i=%d\n", 
     142                     cbBeforeSub, cbAfterSubFree, cbAfterSubAlloc, i); 
     143            //return 1; - won't work correctly until we start creating free block instead of donating memory on alignment. 
    139144        } 
    140         aOps[i].pvAlloc = pv; 
    141         #if 0 /* won't work :/ */ 
    142         size_t cbAfterSub = RTHeapSimpleGetFreeSize(Heap); 
    143         if (cbBeforeSub != cbAfterSub) 
    144         { 
    145             RTPrintf("Failure: cbBeforeSub=%d cbAfterSub=%d. i=%d\n", cbBeforeSub, cbAfterSub, i); 
    146             return 1; 
    147         } 
    148         #endif 
    149145    } 
    150146 
     
    160156                continue; 
    161157            //RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, RTHeapSimpleGetFreeSize(Heap), aOps[j].cb, aOps[j].pvAlloc); 
    162             if (aOps[j].uAlignment == PAGE_SIZE) 
    163                 cbBefore -= aOps[j].cb; 
    164             else 
    165                 RTHeapSimpleFree(Heap, aOps[j].pvAlloc); 
     158            RTHeapSimpleFree(Heap, aOps[j].pvAlloc); 
    166159            aOps[j].pvAlloc = NULL; 
    167160            cFreed++; 
     
    169162    } 
    170163    Assert(cFreed == RT_ELEMENTS(aOps)); 
    171     //RTPrintf("i=done free=%d\n", RTHeapSimpleGetFreeSize(Heap)); 
     164    RTPrintf("i=done free=%d\n", RTHeapSimpleGetFreeSize(Heap)); 
    172165 
    173 #if 0 
    174166    /* check that we're back at the right amount of free memory. */ 
    175     //size_t cbAfter = RTHeapSimpleGetFreeSize(Heap); 
     167    size_t cbAfter = RTHeapSimpleGetFreeSize(Heap); 
    176168    if (cbBefore != cbAfter) 
    177169    { 
    178170        RTPrintf("Warning: Either we've split out an alignment chunk at the start, or we've got\n" 
    179171                 "         an alloc/free accounting bug: cbBefore=%d cbAfter=%d\n", cbBefore, cbAfter); 
    180 #ifdef DEBUG 
    181         RTHeapSimpleDump(Heap); 
    182 #endif 
     172        RTHeapSimpleDump(Heap, (PFNRTHEAPSIMPLEPRINTF)RTPrintf); 
    183173    } 
    184 #endif  
    185174 
    186175    RTPrintf("tstHeapSimple: Success\n"); 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy