Changeset 288 in vbox
- Timestamp:
- Jan 25, 2007 5:14:15 AM (18 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/heap.h
r283 r288 33 33 /** Pointer to a handle to a simple heap. */ 34 34 typedef RTHEAPSIMPLE *PRTHEAPSIMPLE; 35 36 /** NIL simple heap handle. */ 37 #define NIL_RTHEAPSIMPLE ((RTHEAPSIMPLE)0) 35 38 /* <<< types.h */ 36 39 … … 39 42 /** 40 43 * Initializes the heap. 41 * 44 * 42 45 * @returns IPRT status code on success. 43 46 * @param pHeap Where to store the heap anchor block on success. … … 49 52 /** 50 53 * Merge two simple heaps into one. 51 * 54 * 52 55 * The requiremet is of course that they next two each other memory wise. 53 * 56 * 54 57 * @returns IPRT status code on success. 55 58 * @param pHeap Where to store the handle to the merged heap on success. 56 59 * @param Heap1 Handle to the first heap. 57 60 * @param Heap2 Handle to the second heap. 61 * @remark This API isn't implemented yet. 58 62 */ 59 63 RTDECL(int) RTHeapSimpleMerge(PRTHEAPSIMPLE pHeap, RTHEAPSIMPLE Heap1, RTHEAPSIMPLE Heap2); … … 61 65 /** 62 66 * Allocates memory from the specified simple heap. 63 * 67 * 64 68 * @returns Pointer to the allocated memory block on success. 65 69 * @returns NULL if the request cannot be satisfied. (A VERR_NO_MEMORY condition.) 66 * 70 * 67 71 * @param Heap The heap to allocate the memory on. 68 72 * @param cb The requested heap block size. … … 74 78 /** 75 79 * Allocates zeroed memory from the specified simple heap. 76 * 80 * 77 81 * @returns Pointer to the allocated memory block on success. 78 82 * @returns NULL if the request cannot be satisfied. (A VERR_NO_MEMORY condition.) 79 * 83 * 80 84 * @param Heap The heap to allocate the memory on. 81 85 * @param cb The requested heap block size. … … 86 90 87 91 /** 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 */ 101 RTDECL(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 */ 113 RTDECL(void *) RTHeapSimpleReallocZ(RTHEAPSIMPLE Heap, void *pv, size_t cbNew, size_t cbAlignment); 114 115 /** 88 116 * Frees memory allocated from a simple heap. 89 * 117 * 90 118 * @param Heap The heap. This is optional and will only be used for strict assertions. 91 119 * @param pv The heap block returned by RTHeapSimple … … 93 121 RTDECL(void) RTHeapSimpleFree(RTHEAPSIMPLE Heap, void *pv); 94 122 95 #ifdef DEBUG96 123 /** 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 */ 132 RTDECL(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 */ 145 RTDECL(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 */ 157 RTDECL(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 */ 164 typedef DECLCALLBACK(void) FNRTHEAPSIMPLEPRINTF(const char *pszFormat, ...); 165 /** Pointer to a FNRTHEAPSIMPLEPRINTF function. */ 166 typedef FNRTHEAPSIMPLEPRINTF *PFNRTHEAPSIMPLEPRINTF; 167 168 /** 169 * Dumps the hypervisor heap. 170 * 99 171 * @param Heap The heap handle. 172 * @param pfnPrintf Printf like function that groks IPRT formatting. 100 173 */ 101 RTDECL(void) RTHeapSimpleDump(RTHEAPSIMPLE Heap); 102 #endif 103 174 RTDECL(void) RTHeapSimpleDump(RTHEAPSIMPLE Heap, PFNRTHEAPSIMPLEPRINTF pfnPrintf); 104 175 105 176 __END_DECLS 106 177 107 #endif 178 #endif 108 179 -
trunk/src/VBox/Runtime/testcase/tstHeapSimple.cpp
r283 r288 68 68 } aOps[] = 69 69 { 70 { 16, 0, NULL, 0 }, 70 { 16, 0, NULL, 0 }, // 0 71 71 { 16, 4, NULL, 1 }, 72 72 { 16, 8, NULL, 2 }, 73 73 { 16, 16, NULL, 5 }, 74 74 { 16, 32, NULL, 4 }, 75 { 32, 0, NULL, 3 }, 75 { 32, 0, NULL, 3 }, // 5 76 76 { 31, 0, NULL, 6 }, 77 77 { 1024, 0, NULL, 8 }, 78 78 { 1024, 32, NULL, 10 }, 79 79 { 1024, 32, NULL, 12 }, 80 { PAGE_SIZE, PAGE_SIZE, NULL, 13 }, 80 { PAGE_SIZE, PAGE_SIZE, NULL, 13 }, // 10 81 81 { 1024, 32, NULL, 9 }, 82 82 { PAGE_SIZE, 32, NULL, 11 }, 83 83 { PAGE_SIZE, PAGE_SIZE, NULL, 14 }, 84 84 { 16, 0, NULL, 15 }, 85 { 9, 0, NULL, 7 }, 85 { 9, 0, NULL, 7 }, // 15 86 86 { 16, 0, NULL, 7 }, 87 87 { 36, 0, NULL, 7 }, 88 88 { 16, 0, NULL, 7 }, 89 89 { 12344, 0, NULL, 7 }, 90 { 50, 0, NULL, 7 }, 90 { 50, 0, NULL, 7 }, // 20 91 91 { 16, 0, NULL, 7 }, 92 92 }; 93 93 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); 99 96 static char szFill[] = "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 100 97 … … 119 116 for (i = 0; i < ELEMENTS(aOps); i++) 120 117 { 121 if ( !aOps[i].pvAlloc 122 || aOps[i].uAlignment == PAGE_SIZE) 118 if (!aOps[i].pvAlloc) 123 119 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); 125 123 RTHeapSimpleFree(Heap, aOps[i].pvAlloc); 124 size_t cbAfterSubFree = RTHeapSimpleGetFreeSize(Heap); 126 125 127 //RTPrintf("debug: i=%d cbBeforeSub=%d now=%d\n", i, cbBeforeSub, RTHeapSimpleGetFreeSize(Heap));128 126 void *pv; 129 127 pv = RTHeapSimpleAlloc(Heap, aOps[i].cb, aOps[i].uAlignment); 130 if ( pv)128 if (!pv) 131 129 { 132 130 RTPrintf("Failure: RTHeapSimpleAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, aOps[i].cb, aOps[i].uAlignment, i); 133 131 return 1; 134 132 } 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)); 135 135 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) 136 140 { 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. 139 144 } 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 #endif149 145 } 150 146 … … 160 156 continue; 161 157 //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); 166 159 aOps[j].pvAlloc = NULL; 167 160 cFreed++; … … 169 162 } 170 163 Assert(cFreed == RT_ELEMENTS(aOps)); 171 //RTPrintf("i=done free=%d\n", RTHeapSimpleGetFreeSize(Heap));164 RTPrintf("i=done free=%d\n", RTHeapSimpleGetFreeSize(Heap)); 172 165 173 #if 0174 166 /* check that we're back at the right amount of free memory. */ 175 //size_t cbAfter = RTHeapSimpleGetFreeSize(Heap);167 size_t cbAfter = RTHeapSimpleGetFreeSize(Heap); 176 168 if (cbBefore != cbAfter) 177 169 { 178 170 RTPrintf("Warning: Either we've split out an alignment chunk at the start, or we've got\n" 179 171 " 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); 183 173 } 184 #endif185 174 186 175 RTPrintf("tstHeapSimple: Success\n");
Note:
See TracChangeset
for help on using the changeset viewer.