Changeset 20575 in vbox for trunk/src/VBox/Runtime/testcase/tstRTMemPool.cpp
- Timestamp:
- Jun 15, 2009 1:52:07 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/testcase/tstRTMemPool.cpp
r20562 r20575 34 34 #include <iprt/mempool.h> 35 35 36 #include <iprt/asm.h> 36 37 #include <iprt/err.h> 37 38 #include <iprt/initterm.h> 38 #include <iprt/stdarg.h>39 39 #include <iprt/string.h> 40 40 #include <iprt/test.h> 41 41 #include <iprt/thread.h> 42 #include <iprt/rand.h> 43 44 45 /******************************************************************************* 46 * Global Variables * 47 *******************************************************************************/ 48 /** The test handle */ 49 static RTTEST g_hTest; 50 /** Memory pool for tst4. */ 51 static RTMEMPOOL g_hMemPool4; 52 53 54 /** 55 * Basic API checks. 56 * We'll return if any of these fails. 57 */ 58 static void tst1(RTMEMPOOL hMemPool) 59 { 60 void *pv; 61 62 /* Normal alloc. */ 63 RTTESTI_CHECK_RETV(pv = RTMemPoolAlloc(hMemPool, 1)); 64 RTTESTI_CHECK_RETV(RTMemPoolRelease(hMemPool, pv) == 0); 65 66 RTTESTI_CHECK_RETV(pv = RTMemPoolAlloc(hMemPool, 0)); 67 RTTESTI_CHECK_RETV(RTMemPoolRelease(hMemPool, pv) == 0); 68 69 /* Zeroed allocation. */ 70 for (uint32_t i = 0; i < 512; i++) 71 { 72 RTTESTI_CHECK_RETV(pv = RTMemPoolAllocZ(hMemPool, 1024)); 73 RTTESTI_CHECK(ASMMemIsAllU32(pv, 1024, 0) == NULL); 74 memset(pv, 'a', 1024); 75 RTTESTI_CHECK_RETV(RTMemPoolRelease(hMemPool, pv) == 0); 76 } 77 78 RTTESTI_CHECK_RETV(pv = RTMemPoolAllocZ(hMemPool, 0)); 79 RTTESTI_CHECK_RETV(RTMemPoolRelease(hMemPool, pv) == 0); 80 81 /* Duped allocation. */ 82 static const char szTest[] = "test string abcdef"; 83 RTTESTI_CHECK_RETV(pv = RTMemPoolDup(hMemPool, szTest, sizeof(szTest))); 84 RTTESTI_CHECK(memcmp(pv, szTest, sizeof(szTest)) == 0); 85 RTTESTI_CHECK_RETV(RTMemPoolRelease(hMemPool, pv) == 0); 86 87 for (uint32_t i = 0; i < 512; i++) 88 { 89 size_t const cb = 256 - sizeof(szTest); 90 RTTESTI_CHECK_RETV(pv = RTMemPoolDupEx(hMemPool, szTest, sizeof(szTest), cb)); 91 RTTESTI_CHECK(memcmp(pv, szTest, sizeof(szTest)) == 0); 92 RTTESTI_CHECK(ASMMemIsAll8((uint8_t *)pv + sizeof(szTest), cb, 0) == NULL); 93 memset(pv, 'b', sizeof(szTest) + cb); 94 RTTESTI_CHECK_RETV(RTMemPoolRelease(hMemPool, pv) == 0); 95 } 96 97 /* Reallocation */ 98 RTTESTI_CHECK_RETV(pv = RTMemPoolRealloc(hMemPool, NULL, 1)); 99 RTTESTI_CHECK_RETV(pv = RTMemPoolRealloc(hMemPool, pv, 2)); 100 RTTESTI_CHECK_RETV(RTMemPoolRelease(hMemPool, pv) == 0); 101 102 RTTESTI_CHECK_RETV(pv = RTMemPoolAlloc(hMemPool, 42)); 103 RTTESTI_CHECK_RETV(pv = RTMemPoolRealloc(hMemPool, pv, 32)); 104 RTTESTI_CHECK_RETV(RTMemPoolRelease(hMemPool, pv) == 0); 105 106 RTTESTI_CHECK_RETV(pv = RTMemPoolRealloc(hMemPool, NULL, 128)); 107 RTTESTI_CHECK_RETV(pv = RTMemPoolRealloc(hMemPool, pv, 256)); 108 RTTESTI_CHECK_RETV(RTMemPoolRealloc(hMemPool, pv, 0) == NULL); 109 110 /* Free (a bit hard to test) */ 111 RTMemPoolFree(hMemPool, NULL); 112 RTMemPoolFree(hMemPool, RTMemPoolAlloc(hMemPool, 42)); 113 114 /* Memory referencing. */ 115 for (uint32_t i = 1; i <= 4096; i *= 3) 116 { 117 void *pv2; 118 RTTESTI_CHECK_RETV(pv = RTMemPoolAlloc(hMemPool, i)); 119 memset(pv, 'a', i); 120 RTTESTI_CHECK_MSG_RETV((pv2 = ASMMemIsAll8(pv, i, 'a')) == NULL, ("i=%#x pv=%p off=%#x\n", i, pv, (uintptr_t)pv2 - (uintptr_t)pv)); 121 RTTESTI_CHECK(RTMemPoolRetain(pv) == 2); 122 RTTESTI_CHECK(RTMemPoolRetain(pv) == 3); 123 RTTESTI_CHECK(RTMemPoolRetain(pv) == 4); 124 RTTESTI_CHECK_MSG_RETV((pv2 = ASMMemIsAll8(pv, i, 'a')) == NULL, ("i=%#x pv=%p off=%#x\n", i, pv, (uintptr_t)pv2 - (uintptr_t)pv)); 125 RTTESTI_CHECK(RTMemPoolRelease(hMemPool, pv) == 3); 126 RTTESTI_CHECK_MSG_RETV((pv2 = ASMMemIsAll8(pv, i, 'a')) == NULL, ("i=%#x pv=%p off=%#x\n", i, pv, (uintptr_t)pv2 - (uintptr_t)pv)); 127 RTTESTI_CHECK(RTMemPoolRetain(pv) == 4); 128 RTTESTI_CHECK(RTMemPoolRetain(pv) == 5); 129 RTTESTI_CHECK(RTMemPoolRetain(pv) == 6); 130 RTTESTI_CHECK(RTMemPoolRelease(NIL_RTMEMPOOL, pv) == 5); 131 RTTESTI_CHECK(RTMemPoolRelease(NIL_RTMEMPOOL, pv) == 4); 132 RTTESTI_CHECK_MSG_RETV((pv2 = ASMMemIsAll8(pv, i, 'a')) == NULL, ("i=%#x pv=%p off=%#x\n", i, pv, (uintptr_t)pv2 - (uintptr_t)pv)); 133 134 for (uint32_t cRefs = 3;; cRefs--) 135 { 136 RTTESTI_CHECK(RTMemPoolRelease(hMemPool, pv) == cRefs); 137 if (cRefs == 0) 138 break; 139 RTTESTI_CHECK_MSG_RETV((pv2 = ASMMemIsAll8(pv, i, 'a')) == NULL, ("i=%#x pv=%p off=%#x cRefs=%d\n", i, pv, (uintptr_t)pv2 - (uintptr_t)pv, cRefs)); 140 for (uint32_t j = 0; j < 42; j++) 141 { 142 RTTESTI_CHECK_RETV(pv2 = RTMemPoolAlloc(hMemPool, i)); 143 RTTESTI_CHECK_RETV(pv2 != pv); 144 memset(pv2, 'f', i); 145 RTTESTI_CHECK(RTMemPoolRelease(hMemPool, pv2) == 0); 146 RTTESTI_CHECK_MSG_RETV((pv2 = ASMMemIsAll8(pv, i, 'a')) == NULL, ("i=%#x pv=%p off=%#x cRefs=%d\n", i, pv, (uintptr_t)pv2 - (uintptr_t)pv, cRefs)); 147 } 148 } 149 } 150 } 151 152 153 /** 154 * Test automatic cleanup upon destruction. 155 */ 156 static void tst3(void) 157 { 158 RTTestISub("Destroy non-empty pool"); 159 160 /* 161 * Nothing freed. 162 */ 163 RTMEMPOOL hMemPool; 164 RTTESTI_CHECK_RC_RETV(RTMemPoolCreate(&hMemPool, "test 3a"), VINF_SUCCESS); 165 RTTESTI_CHECK_RETV(RTMemPoolAlloc(hMemPool, 10)); 166 RTTESTI_CHECK_RETV(RTMemPoolAlloc(hMemPool, 20)); 167 RTTESTI_CHECK_RETV(RTMemPoolAlloc(hMemPool, 40)); 168 RTTESTI_CHECK_RETV(RTMemPoolAlloc(hMemPool, 80)); 169 RTTESTI_CHECK_RC_RETV(RTMemPoolDestroy(hMemPool), VINF_SUCCESS); 170 171 /* 172 * Pseudo random freeing to test list maintaince. 173 */ 174 RTRAND hRand; 175 RTTESTI_CHECK_RC_OK_RETV(RTRandAdvCreateParkMiller(&hRand)); 176 177 for (uint32_t i = 0; i < 10; i++) 178 { 179 RTTESTI_CHECK_RC_RETV(RTMemPoolCreate(&hMemPool, "test 3b"), VINF_SUCCESS); 180 181 void *apvHistory[256]; 182 RT_ZERO(apvHistory); 183 184 uint32_t cBlocks = 0; 185 uint32_t j; 186 for (j = 0; j < RT_ELEMENTS(apvHistory) - i * 7; j++) 187 { 188 RTTESTI_CHECK_RETV(apvHistory[j] = RTMemPoolAlloc(hMemPool, j)); 189 memset(apvHistory[j], 'a', j); 190 cBlocks++; 191 192 if (RTRandAdvU32Ex(hRand, 0, 4) == 4) 193 { 194 uint32_t iFree = RTRandAdvU32Ex(hRand, 0, j); 195 cBlocks -= apvHistory[iFree] != NULL; 196 RTTESTI_CHECK_RETV(RTMemPoolRelease(hMemPool, apvHistory[iFree]) == 0); 197 apvHistory[iFree] = NULL; 198 } 199 } 200 201 RTTESTI_CHECK_RC_RETV(RTMemPoolDestroy(hMemPool), VINF_SUCCESS); 202 RTTestIPrintf(RTTESTLVL_INFO, "cBlocks=%u j=%u\n", cBlocks, j); 203 } 204 205 RTRandAdvDestroy(hRand); 206 } 207 208 209 /** Thread function for tst4. */ 210 static DECLCALLBACK(int) tst4Thread(RTTHREAD hSelf, void *pvArg) 211 { 212 // uint32_t iThread = (uint32_t)(uintptr_t)pvArg; 213 RTMEMPOOL hMemPool = g_hMemPool4; 214 215 /* setup. */ 216 RTTestSetDefault(g_hTest, NULL); 217 218 /* wait for the kick-off */ 219 RTThreadUserWait(hSelf, RT_INDEFINITE_WAIT); 220 221 /* do the work. */ 222 for (uint32_t i = 0; i < 1024; i++) 223 { 224 void *apvHistory[256]; 225 RT_ZERO(apvHistory); 226 uint32_t j; 227 for (j = 0; j < RT_ELEMENTS(apvHistory) - (i % 200); j++) 228 RTTESTI_CHECK_RET(apvHistory[j] = RTMemPoolAlloc(hMemPool, (i & 15) + (j & 63)), VERR_NO_MEMORY); 229 for (uint32_t k = i & 7; k < j; k += 3) 230 { 231 RTTESTI_CHECK_RET(RTMemPoolRelease(hMemPool, apvHistory[k]) == 0, VERR_INTERNAL_ERROR); 232 apvHistory[k] = NULL; 233 } 234 while (j-- > 0) 235 RTTESTI_CHECK_RET(RTMemPoolRelease(hMemPool, apvHistory[j]) == 0, VERR_INTERNAL_ERROR); 236 } 237 238 return VINF_SUCCESS; 239 } 240 241 /** sub test */ 242 static void tst4Sub(uint32_t cThreads) 243 { 244 RTTestISubF("Serialization - %u threads", cThreads); 245 RTMEMPOOL hMemPool; 246 RTTESTI_CHECK_RC_RETV(RTMemPoolCreate(&hMemPool, "test 2a"), VINF_SUCCESS); 247 g_hMemPool4 = hMemPool; 248 249 PRTTHREAD pahThreads = (PRTTHREAD)RTMemPoolAlloc(hMemPool, cThreads * sizeof(RTTHREAD)); 250 RTTESTI_CHECK(pahThreads); 251 if (pahThreads) 252 { 253 /* start them. */ 254 for (uint32_t i = 0; i < cThreads; i++) 255 { 256 int rc = RTThreadCreateF(&pahThreads[i], tst4Thread, (void *)(uintptr_t)i, 0, 257 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tst4-%u/%u", i, cThreads); 258 RTTESTI_CHECK_RC_OK(rc); 259 if (RT_FAILURE(rc)) 260 pahThreads[i] = NIL_RTTHREAD; 261 } 262 RTThreadYield(); 263 264 /* kick them off. */ 265 for (uint32_t i = 0; i < cThreads; i++) 266 if (pahThreads[i] != NIL_RTTHREAD) 267 RTTESTI_CHECK_RC_OK(RTThreadUserSignal(pahThreads[i])); 268 269 /* wait for them. */ 270 for (uint32_t i = 0; i < cThreads; i++) 271 if (pahThreads[i] != NIL_RTTHREAD) 272 { 273 int rc = RTThreadWait(pahThreads[i], 2*60*1000, NULL); 274 RTTESTI_CHECK_RC_OK(rc); 275 } 276 } 277 278 RTTESTI_CHECK_RC(RTMemPoolDestroy(hMemPool), VINF_SUCCESS); 279 } 280 281 282 /** 283 * Starts a bunch of threads beating on a pool to test serialization. 284 */ 285 static void tst4(void) 286 { 287 /* 288 * Test it with a few different thread counts. 289 */ 290 tst4Sub(1); 291 tst4Sub(2); 292 tst4Sub(3); 293 tst4Sub(4); 294 tst4Sub(8); 295 tst4Sub(16); 296 } 42 297 43 298 … … 51 306 if (RT_FAILURE(rc)) 52 307 return 1; 308 g_hTest = hTest; 53 309 RTTestBanner(hTest); 54 310 … … 56 312 * Smoke tests using first the default and then a custom pool. 57 313 */ 58 59 314 RTTestSub(hTest, "Smoke test on default pool"); 315 tst1(RTMEMPOOL_DEFAULT); 316 317 RTTestSub(hTest, "Smoke test on custom pool"); 318 RTMEMPOOL hMemPool; 319 RTTESTI_CHECK_RC(rc = RTMemPoolCreate(&hMemPool, "test 2a"), VINF_SUCCESS); 320 if (RT_SUCCESS(rc)) 321 RTTESTI_CHECK_RC(rc = RTMemPoolDestroy(hMemPool), VINF_SUCCESS); 322 RTTESTI_CHECK_RC(rc = RTMemPoolDestroy(NIL_RTMEMPOOL), VINF_SUCCESS); 323 RTTESTI_CHECK_RC(rc = RTMemPoolDestroy(RTMEMPOOL_DEFAULT), VINF_SUCCESS); 324 RTTESTI_CHECK_RC(rc = RTMemPoolDestroy(RTMEMPOOL_DEFAULT), VINF_SUCCESS); 325 326 RTTESTI_CHECK_RC(rc = RTMemPoolCreate(&hMemPool, "test 2b"), VINF_SUCCESS); 327 if (RT_SUCCESS(rc)) 328 { 329 tst1(hMemPool); 330 RTTESTI_CHECK_RC(rc = RTMemPoolDestroy(hMemPool), VINF_SUCCESS); 331 } 332 333 /* 334 * Further tests. 335 */ 336 tst3(); 337 tst4(); 60 338 61 339 /*
Note:
See TracChangeset
for help on using the changeset viewer.