儲存庫 vbox 的更動 10788
圖例:
- 未更動
- 新增
- 刪除
-
trunk/include/iprt/handletable.h
r10768 r10788 98 98 * If not specfied the caller will have to take care of that. */ 99 99 #define RTHANDLETABLE_FLAGS_LOCKED RT_BIT_32(1) 100 /** The mask of valid flags. */ 101 #define RTHANDLETABLE_FLAGS_MASK UINT32_C(0x00000003) 100 102 /* @} */ 101 103 … … 116 118 * first handle to be returned. 117 119 * @param cMax The max number of handles. When exceeded the RTHandleTableAlloc 118 * or RTHandleTableAllocWithCtx calls will fail. 120 * or RTHandleTableAllocWithCtx calls will fail. Note that this 121 * number will be rounded up to a multiple of the sub-table size, 122 * or if it's too close to UINT32_MAX it will be rounded down. 119 123 * @param pfnRetain Optional retain callback that will be called from behind the 120 124 * lock (if any) during lookup. … … 127 131 * A simplified version of the RTHandleTableCreateEx API. 128 132 * 129 * It assumes a max of 65534handles with 1 being the base. The table130 * serialized (RTHANDLETABLE_FLAGS_LOCKED).133 * It assumes a max of about 64K handles with 1 being the base. The table 134 * access will serialized (RTHANDLETABLE_FLAGS_LOCKED). 131 135 * 132 136 * @returns IPRT status code and *phHandleTable. -
trunk/src/VBox/Runtime/common/misc/handletable.cpp
r10768 r10788 39 39 #include <iprt/param.h> 40 40 #include <iprt/string.h> 41 #include <iprt/asm.h> 41 42 #include "internal/magics.h" 42 43 … … 59 60 #define RTHT_SET_FREE_IDX(pFree, idx) \ 60 61 do { \ 61 (pFree)->iNext = ((uintptr_t)( idx) << 2) | 3; \62 (pFree)->iNext = ((uintptr_t)((uint32_t)(idx)) << 2) | 3U; \ 62 63 } while (0) 63 64 … … 99 100 typedef struct RTHTENTRYCTX 100 101 { 102 /** The object. */ 103 void *pvObj; 101 104 /** The context. */ 102 105 void *pvCtx; 103 /** The object. */104 void *pvObj;105 106 } RTHTENTRYCTX; 106 107 /** Pointer to a handle table entry, context variant. */ … … 126 127 AssertCompile(sizeof(RTHTENTRYFREE) <= sizeof(RTHTENTRY)); 127 128 AssertCompile(sizeof(RTHTENTRYFREE) <= sizeof(RTHTENTRYCTX)); 129 AssertCompileMemberOffset(RTHTENTRYFREE, iNext, 0); 130 AssertCompileMemberOffset(RTHTENTRY, pvObj, 0); 131 AssertCompileMemberOffset(RTHTENTRYCTX, pvObj, 0); 128 132 129 133 … … 139 143 /** The base handle value (i.e. the first handle). */ 140 144 uint32_t uBase; 141 /** The current number of handles. 142 * This indirectly gives the size of the first level lookup table. */ 145 /** The current number of handle table entries. */ 143 146 uint32_t cCur; 144 147 /** The spinlock handle (NIL if RTHANDLETABLE_FLAGS_LOCKED wasn't used). */ … … 165 168 166 169 167 168 /** 169 * Looks up a simple handle. 170 /** 171 * Looks up a simple index. 170 172 * 171 173 * @returns Pointer to the handle table entry on success, NULL on failure. 172 174 * @param pThis The handle table structure. 173 * @param h The handle to look up. 174 */ 175 DECLINLINE(PRTHTENTRY) rtHandleTableLookupSimple(PRTHANDLETABLEINT pThis, uint32_t h) 176 { 177 uint32_t i = h - pThis->uBase; 175 * @param i The index to look up. 176 */ 177 DECLINLINE(PRTHTENTRY) rtHandleTableLookupSimpleIdx(PRTHANDLETABLEINT pThis, uint32_t i) 178 { 178 179 if (i < pThis->cCur) 179 180 { … … 182 183 return &paTable[i % RTHT_LEVEL2_ENTRIES]; 183 184 } 184 185 185 return NULL; 186 186 } … … 188 188 189 189 /** 190 * Looks up a contexthandle.190 * Looks up a simple handle. 191 191 * 192 192 * @returns Pointer to the handle table entry on success, NULL on failure. … … 194 194 * @param h The handle to look up. 195 195 */ 196 DECLINLINE(PRTHTENTRYCTX) rtHandleTableLookupWithCtx(PRTHANDLETABLEINT pThis, uint32_t h) 197 { 198 uint32_t i = h - pThis->uBase; 196 DECLINLINE(PRTHTENTRY) rtHandleTableLookupSimple(PRTHANDLETABLEINT pThis, uint32_t h) 197 { 198 return rtHandleTableLookupSimpleIdx(pThis, h - pThis->uBase); 199 } 200 201 202 /** 203 * Looks up a context index. 204 * 205 * @returns Pointer to the handle table entry on success, NULL on failure. 206 * @param pThis The handle table structure. 207 * @param i The index to look up. 208 */ 209 DECLINLINE(PRTHTENTRYCTX) rtHandleTableLookupWithCtxIdx(PRTHANDLETABLEINT pThis, uint32_t i) 210 { 199 211 if (i < pThis->cCur) 200 212 { … … 203 215 return &paTable[i % RTHT_LEVEL2_ENTRIES]; 204 216 } 205 206 217 return NULL; 207 218 } 208 219 209 220 221 /** 222 * Looks up a context handle. 223 * 224 * @returns Pointer to the handle table entry on success, NULL on failure. 225 * @param pThis The handle table structure. 226 * @param h The handle to look up. 227 */ 228 DECLINLINE(PRTHTENTRYCTX) rtHandleTableLookupWithCtx(PRTHANDLETABLEINT pThis, uint32_t h) 229 { 230 return rtHandleTableLookupWithCtxIdx(pThis, h - pThis->uBase); 231 } 232 233 234 /** 235 * Locks the handle table. 236 * 237 * @param pThis The handle table structure. 238 * @param pTmp The spinlock temp variable. 239 */ 210 240 DECLINLINE(void) rtHandleTableLock(PRTHANDLETABLEINT pThis, PRTSPINLOCKTMP pTmp) 241 { 242 if (pThis->hSpinlock != NIL_RTSPINLOCK) 243 { 244 RTSPINLOCKTMP const Tmp = RTSPINLOCKTMP_INITIALIZER; 245 *pTmp = Tmp; 246 RTSpinlockAcquire(pThis->hSpinlock, pTmp); 247 } 248 } 249 250 251 /** 252 * Locks the handle table. 253 * 254 * @param pThis The handle table structure. 255 * @param pTmp The spinlock temp variable. 256 */ 257 DECLINLINE(void) rtHandleTableUnlock(PRTHANDLETABLEINT pThis, PRTSPINLOCKTMP pTmp) 211 258 { 212 259 if (pThis->hSpinlock != NIL_RTSPINLOCK) … … 215 262 216 263 217 DECLINLINE(void) rtHandleTableUnlock(PRTHANDLETABLEINT pThis, PRTSPINLOCKTMP pTmp) 218 { 264 RTDECL(int) RTHandleTableCreateEx(PRTHANDLETABLE phHandleTable, uint32_t fFlags, uint32_t uBase, uint32_t cMax, 265 PFNRTHANDLETABLERETAIN pfnRetain, void *pvUser) 266 { 267 /* 268 * Validate input. 269 */ 270 AssertPtrReturn(phHandleTable, VERR_INVALID_POINTER); 271 *phHandleTable = NIL_RTHANDLETABLE; 272 AssertPtrNullReturn(pfnRetain, VERR_INVALID_POINTER); 273 AssertReturn(!(fFlags & ~RTHANDLETABLE_FLAGS_MASK), VERR_INVALID_PARAMETER); 274 AssertReturn(cMax > 0, VERR_INVALID_PARAMETER); 275 AssertReturn(UINT32_MAX - cMax >= uBase, VERR_INVALID_PARAMETER); 276 277 /* 278 * Adjust the cMax value so it is a multiple of the 2nd level tables. 279 */ 280 if (cMax >= UINT32_MAX - RTHT_LEVEL2_ENTRIES) 281 cMax = UINT32_MAX - RTHT_LEVEL2_ENTRIES + 1; 282 cMax = ((cMax + RTHT_LEVEL2_ENTRIES - 1) / RTHT_LEVEL2_ENTRIES) * RTHT_LEVEL2_ENTRIES; 283 284 uint32_t const cLevel1 = cMax / RTHT_LEVEL2_ENTRIES; 285 Assert(cLevel1 * RTHT_LEVEL2_ENTRIES == cMax); 286 287 /* 288 * Allocate the structure, include the 1st level lookup table 289 * if it's below the threshold size. 290 */ 291 size_t cb = sizeof(RTHANDLETABLEINT); 292 if (cLevel1 < RTHT_LEVEL1_DYN_ALLOC_THRESHOLD) 293 cb = RT_ALIGN(cb, sizeof(void *)) + cLevel1 * sizeof(void *); 294 PRTHANDLETABLEINT pThis = (PRTHANDLETABLEINT)RTMemAllocZ(cb); 295 if (!pThis) 296 return VERR_NO_MEMORY; 297 298 /* 299 * Initialize it. 300 */ 301 pThis->u32Magic = RTHANDLETABLE_MAGIC; 302 pThis->fFlags = fFlags; 303 pThis->uBase = uBase; 304 pThis->cCur = 0; 305 pThis->hSpinlock = NIL_RTSPINLOCK; 306 if (cLevel1 < RTHT_LEVEL1_DYN_ALLOC_THRESHOLD) 307 pThis->papvLevel1 = (void **)((uint8_t *)pThis + RT_ALIGN(sizeof(*pThis), sizeof(void *))); 308 else 309 pThis->papvLevel1 = NULL; 310 pThis->pfnRetain = pfnRetain; 311 pThis->pvRetainUser = pvUser; 312 pThis->cMax = cMax; 313 pThis->cCurAllocated = 0; 314 pThis->cLevel1 = cLevel1 < RTHT_LEVEL1_DYN_ALLOC_THRESHOLD ? cLevel1 : 0; 315 pThis->iFreeHead = NIL_RTHT_INDEX; 316 pThis->iFreeTail = NIL_RTHT_INDEX; 317 if (fFlags & RTHANDLETABLE_FLAGS_LOCKED) 318 { 319 int rc = RTSpinlockCreate(&pThis->hSpinlock); 320 if (RT_FAILURE(rc)) 321 { 322 RTMemFree(pThis); 323 return rc; 324 } 325 } 326 327 *phHandleTable = pThis; 328 return VINF_SUCCESS; 329 } 330 331 332 RTDECL(int) RTHandleTableCreate(PRTHANDLETABLE phHandleTable) 333 { 334 return RTHandleTableCreateEx(phHandleTable, RTHANDLETABLE_FLAGS_LOCKED, 1, 65534, NULL, NULL); 335 } 336 337 338 RTDECL(int) RTHandleTableDestroy(RTHANDLETABLE hHandleTable, PFNRTHANDLETABLEDELETE pfnDelete, void *pvUser) 339 { 340 /* 341 * Validate input, quitely ignore the NIL handle. 342 */ 343 if (hHandleTable == NIL_RTHANDLETABLE) 344 return VINF_SUCCESS; 345 PRTHANDLETABLEINT pThis = (PRTHANDLETABLEINT)hHandleTable; 346 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 347 AssertReturn(pThis->u32Magic == RTHANDLETABLE_MAGIC, VERR_INVALID_HANDLE); 348 AssertPtrNullReturn(pfnDelete, VERR_INVALID_POINTER); 349 350 /* 351 * Mark the thing as invalid / deleted. 352 * Then kill the lock. 353 */ 354 RTSPINLOCKTMP Tmp; 355 rtHandleTableLock(pThis, &Tmp); 356 ASMAtomicWriteU32(&pThis->u32Magic, ~RTHANDLETABLE_MAGIC); 357 rtHandleTableUnlock(pThis, &Tmp); 358 219 359 if (pThis->hSpinlock != NIL_RTSPINLOCK) 220 RTSpinlockAcquire(pThis->hSpinlock, pTmp); 221 } 222 223 224 RTDECL(int) RTHandleTableCreateEx(PRTHANDLETABLE phHandleTable, uint32_t fFlags, uint32_t uBase, uint32_t cMax, 225 PFNRTHANDLETABLERETAIN pfnRetain, void *pvUser) 226 { 227 return VERR_NOT_IMPLEMENTED; 228 } 229 230 231 RTDECL(int) RTHandleTableCreate(PRTHANDLETABLE phHandleTable) 232 { 233 return RTHandleTableCreateEx(phHandleTable, RTHANDLETABLE_FLAGS_LOCKED, 1, 65534, NULL, NULL); 234 } 235 236 237 RTDECL(int) RTHandleTableDestroy(RTHANDLETABLE hHandleTable, PFNRTHANDLETABLEDELETE pfnDelete, void *pvUser) 238 { 239 return -1; 360 { 361 rtHandleTableLock(pThis, &Tmp); 362 rtHandleTableUnlock(pThis, &Tmp); 363 364 RTSpinlockDestroy(pThis->hSpinlock); 365 pThis->hSpinlock = NIL_RTSPINLOCK; 366 } 367 368 if (pfnDelete) 369 { 370 /* 371 * Walk all the tables looking for used handles. 372 */ 373 uint32_t cLeft = pThis->cCurAllocated; 374 if (pThis->fFlags & RTHANDLETABLE_FLAGS_CONTEXT) 375 { 376 for (uint32_t i1 = 0; cLeft > 0 && i1 < pThis->cLevel1; i1++) 377 { 378 PRTHTENTRYCTX paTable = (PRTHTENTRYCTX)pThis->papvLevel1[i1]; 379 if (paTable) 380 for (uint32_t i = 0; i < RTHT_LEVEL2_ENTRIES; i++) 381 if (!RTHT_IS_FREE(paTable[i].pvObj)) 382 { 383 pfnDelete(hHandleTable, pThis->uBase + i + i1 * RTHT_LEVEL2_ENTRIES, 384 paTable[i].pvObj, paTable[i].pvCtx, pvUser); 385 Assert(cLeft > 0); 386 cLeft--; 387 } 388 } 389 } 390 else 391 { 392 for (uint32_t i1 = 0; cLeft > 0 && i1 < pThis->cLevel1; i1++) 393 { 394 PRTHTENTRY paTable = (PRTHTENTRY)pThis->papvLevel1[i1]; 395 if (paTable) 396 for (uint32_t i = 0; i < RTHT_LEVEL2_ENTRIES; i++) 397 if (!RTHT_IS_FREE(paTable[i].pvObj)) 398 { 399 pfnDelete(hHandleTable, pThis->uBase + i + i1 * RTHT_LEVEL2_ENTRIES, 400 paTable[i].pvObj, NULL, pvUser); 401 Assert(cLeft > 0); 402 cLeft--; 403 } 404 } 405 } 406 Assert(!cLeft); 407 } 408 409 /* 410 * Free the memory. 411 */ 412 for (uint32_t i1 = 0; i1 < pThis->cLevel1; i1++) 413 if (pThis->papvLevel1[i1]) 414 { 415 RTMemFree(pThis->papvLevel1[i1]); 416 pThis->papvLevel1[i1] = NULL; 417 } 418 419 if (pThis->cMax / RTHT_LEVEL2_ENTRIES >= RTHT_LEVEL1_DYN_ALLOC_THRESHOLD) 420 RTMemFree(pThis->papvLevel1); 421 422 RTMemFree(pThis); 423 424 return VINF_SUCCESS; 240 425 } 241 426 … … 289 474 AssertReturn(pThis->u32Magic == RTHANDLETABLE_MAGIC, VERR_INVALID_HANDLE); 290 475 AssertReturn(pThis->fFlags & RTHANDLETABLE_FLAGS_CONTEXT, VERR_INVALID_FUNCTION); 291 AssertReturn( RTHT_IS_FREE(pvObj), VERR_INVALID_PARAMETER);476 AssertReturn(!RTHT_IS_FREE(pvObj), VERR_INVALID_PARAMETER); 292 477 AssertPtrReturn(ph, VERR_INVALID_POINTER); 293 478 *ph = pThis->uBase - 1; … … 296 481 * Allocation loop. 297 482 */ 298 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;483 RTSPINLOCKTMP Tmp; 299 484 rtHandleTableLock(pThis, &Tmp); 300 485 … … 308 493 if (i != NIL_RTHT_INDEX) 309 494 { 310 PRTHTENTRYFREE pFree = (PRTHTENTRYFREE)rtHandleTableLookupWithCtx (pThis, i + pThis->uBase);495 PRTHTENTRYFREE pFree = (PRTHTENTRYFREE)rtHandleTableLookupWithCtxIdx(pThis, i); 311 496 Assert(pFree); 312 497 if (i == pThis->iFreeTail) … … 340 525 */ 341 526 uint32_t const iLevel1 = pThis->cCur / RTHT_LEVEL2_ENTRIES; 342 uint32_t cLevel1 = iLevel1 + 1>= pThis->cLevel1527 uint32_t cLevel1 = iLevel1 >= pThis->cLevel1 343 528 ? pThis->cLevel1 + PAGE_SIZE / sizeof(void *) 344 529 : 0; 345 530 if (cLevel1 > pThis->cMax / RTHT_LEVEL2_ENTRIES) 346 531 cLevel1 = pThis->cMax / RTHT_LEVEL2_ENTRIES; 532 Assert(!cLevel1 || pThis->cMax / RTHT_LEVEL2_ENTRIES >= RTHT_LEVEL1_DYN_ALLOC_THRESHOLD); 347 533 348 534 /* leave the lock (never do fancy stuff from behind a spinlock). */ … … 375 561 * raced us expanding the table. 376 562 */ 377 563 /* deal with the 1st level lookup expansion first */ 378 564 if (cLevel1) 379 565 { 566 Assert(papvLevel1); 380 567 if (cLevel1 > pThis->cLevel1) 381 568 { … … 383 570 memcpy(papvLevel1, pThis->papvLevel1, sizeof(void *) * pThis->cLevel1); 384 571 memset(&papvLevel1[pThis->cLevel1], 0, sizeof(void *) * (cLevel1 - pThis->cLevel1)); 572 pThis->cLevel1 = cLevel1; 385 573 void **papvTmp = pThis->papvLevel1; 386 574 pThis->papvLevel1 = papvLevel1; … … 389 577 390 578 /* free the obsolete one (outside the lock of course) */ 579 rtHandleTableUnlock(pThis, &Tmp); 580 RTMemFree(papvLevel1); 391 581 rtHandleTableLock(pThis, &Tmp); 392 RTMemFree(papvLevel1);393 rtHandleTableUnlock(pThis, &Tmp);394 582 } 395 583 … … 404 592 for (uint32_t i = 0; i < RTHT_LEVEL2_ENTRIES - 1; i++) 405 593 { 406 RTHT_SET_FREE_IDX((PRTHTENTRYFREE)&paTable[i], i + 1 );594 RTHT_SET_FREE_IDX((PRTHTENTRYFREE)&paTable[i], i + 1 + pThis->cCur); 407 595 paTable[i].pvCtx = (void *)~(uintptr_t)7; 408 596 } … … 415 603 else 416 604 { 417 PRTHTENTRYFREE pPrev = (PRTHTENTRYFREE)rtHandleTableLookupWithCtx (pThis, pThis->iFreeTail);605 PRTHTENTRYFREE pPrev = (PRTHTENTRYFREE)rtHandleTableLookupWithCtxIdx(pThis, pThis->iFreeTail); 418 606 Assert(pPrev); 419 607 RTHT_SET_FREE_IDX(pPrev, pThis->cCur); … … 426 614 { 427 615 /* free the table (raced someone, and we lost). */ 616 rtHandleTableUnlock(pThis, &Tmp); 617 RTMemFree(paTable); 428 618 rtHandleTableLock(pThis, &Tmp); 429 RTMemFree(paTable);430 rtHandleTableUnlock(pThis, &Tmp);431 619 } 432 620 … … 452 640 453 641 /* acquire the lock */ 454 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;642 RTSPINLOCKTMP Tmp; 455 643 rtHandleTableLock(pThis, &Tmp); 456 644 … … 492 680 493 681 /* acquire the lock */ 494 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;682 RTSPINLOCKTMP Tmp; 495 683 rtHandleTableLock(pThis, &Tmp); 496 684 … … 526 714 else 527 715 { 528 PRTHTENTRYFREE pPrev = (PRTHTENTRYFREE)rtHandleTableLookupWithCtx (pThis, pThis->iFreeTail + pThis->uBase);716 PRTHTENTRYFREE pPrev = (PRTHTENTRYFREE)rtHandleTableLookupWithCtxIdx(pThis, pThis->iFreeTail); 529 717 Assert(pPrev); 530 718 RTHT_SET_FREE_IDX(pPrev, i); -
trunk/src/VBox/Runtime/testcase/Makefile.kmk
r10419 r10788 63 63 tstFileLock \ 64 64 tstGetOpt \ 65 tstHandleTable \ 65 66 tstHeapSimple \ 66 67 tstInlineAsm \ … … 153 154 tstGetOpt_SOURCES = tstGetOpt.cpp 154 155 156 tstHandleTable_SOURCES = tstHandleTable.cpp 157 155 158 tstHeapSimple_SOURCES = tstHeapSimple.cpp 156 159 -
trunk/src/VBox/Runtime/testcase/tstHandleTable.cpp
r10772 r10788 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT Testcase - Native Loader.3 * IPRT Testcase - Handle Tables. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 200 6-2007Sun Microsystems, Inc.7 * Copyright (C) 2008 Sun Microsystems, Inc. 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 29 29 */ 30 30 31 32 #include <iprt/ldr.h> 31 /******************************************************************************* 32 * Header Files * 33 *******************************************************************************/ 34 #include <iprt/handletable.h> 33 35 #include <iprt/stream.h> 34 #include <iprt/ runtime.h>36 #include <iprt/initterm.h> 35 37 #include <iprt/err.h> 36 37 int main(int argc, const char * const *argv) 38 #include <iprt/getopt.h> 39 40 41 /******************************************************************************* 42 * Global Variables * 43 *******************************************************************************/ 44 static unsigned g_cErrors; 45 46 static DECLCALLBACK(void) tstHandleTableTest1Delete(RTHANDLETABLE hHandleTable, uint32_t h, void *pvObj, void *pvCtx, void *pvUser) 38 47 { 39 int rcRet = 0; 40 RTR3Init(); 41 48 uint32_t *pcCalls = (uint32_t *)pvUser; 49 (*pcCalls)++; 50 } 51 52 static DECLCALLBACK(int) tstHandleTableTest1Retain(RTHANDLETABLE hHandleTable, void *pvObj, void *pvCtx, void *pvUser) 53 { 54 uint32_t *pcCalls = (uint32_t *)pvUser; 55 (*pcCalls)++; 56 return VINF_SUCCESS; 57 } 58 59 static int tstHandleTableTest1(uint32_t fFlags, uint32_t uBase, uint32_t cMax, uint32_t cDelta, uint32_t cUnitsPerDot, bool fCallbacks) 60 { 61 int rc; 62 uint32_t cRetainerCalls = 0; 63 64 RTPrintf("tstHandleTable: TESTING RTHandleTableCreateEx(, 0"); 65 fFlags |= RTHANDLETABLE_FLAGS_CONTEXT; 66 if (fFlags & RTHANDLETABLE_FLAGS_LOCKED) RTPrintf(" | LOCKED"); 67 if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT) RTPrintf(" | CONTEXT"); 68 RTPrintf(", %#x, %#x,,)...\n", uBase, cMax); 69 70 RTHANDLETABLE hHT; 71 rc = RTHandleTableCreateEx(&hHT, fFlags, uBase, cMax, 72 fCallbacks ? tstHandleTableTest1Retain : NULL, 73 fCallbacks ? &cRetainerCalls : NULL); 74 if (RT_FAILURE(rc)) 75 { 76 RTPrintf("\ntstHandleTable: FAILURE - RTHandleTableCreateEx failed, %Rrc!\n", rc); 77 return 1; 78 } 79 80 /* fill it */ 81 RTPrintf("tstHandleTable: TESTING RTHandleTableAllocWithCtx.."); RTStrmFlush(g_pStdOut); 82 uint32_t i = uBase; 83 for (;; i++) 84 { 85 uint32_t h; 86 rc = RTHandleTableAllocWithCtx(hHT, (void *)((uintptr_t)&i + (uintptr_t)i * 4), NULL, &h); 87 if (RT_SUCCESS(rc)) 88 { 89 if (h != i) 90 { 91 RTPrintf("\ntstHandleTable: FAILURE (%d) - h=%d, expected %d!\n", __LINE__, h, i); 92 g_cErrors++; 93 } 94 } 95 else if (rc == VERR_NO_MORE_HANDLES) 96 { 97 if (i < cMax) 98 { 99 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, expected > 65534!\n", __LINE__, i); 100 g_cErrors++; 101 } 102 break; 103 } 104 else 105 { 106 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, rc=%Rrc!\n", __LINE__, i, rc); 107 g_cErrors++; 108 } 109 if (!(i % cUnitsPerDot)) 110 { 111 RTPrintf("."); 112 RTStrmFlush(g_pStdOut); 113 } 114 } 115 uint32_t const c = i; 116 RTPrintf(" c=%#x\n", c); 117 if (fCallbacks && cRetainerCalls != 0) 118 { 119 RTPrintf("tstHandleTable: FAILURE (%d) - cRetainerCalls=%#x expected 0!\n", __LINE__, i, cRetainerCalls); 120 g_cErrors++; 121 } 122 123 /* look up all the entries */ 124 RTPrintf("tstHandleTable: TESTING RTHandleTableLookupWithCtx.."); RTStrmFlush(g_pStdOut); 125 cRetainerCalls = 0; 126 for (i = uBase; i < c; i++) 127 { 128 void *pvExpect = (void *)((uintptr_t)&i + (uintptr_t)i * 4); 129 void *pvObj = RTHandleTableLookupWithCtx(hHT, i, NULL); 130 if (!pvObj) 131 { 132 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableLookupWithCtx failed!\n", __LINE__, i); 133 g_cErrors++; 134 } 135 else if (pvObj != pvExpect) 136 { 137 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, pvObj=%p expected %p\n", __LINE__, i, pvObj, pvExpect); 138 g_cErrors++; 139 } 140 if (!(i % cUnitsPerDot)) 141 { 142 RTPrintf("."); 143 RTStrmFlush(g_pStdOut); 144 } 145 } 146 RTPrintf("\n"); 147 if (fCallbacks && cRetainerCalls != c - uBase) 148 { 149 RTPrintf("tstHandleTable: FAILURE (%d) - cRetainerCalls=%#x expected %#x!\n", __LINE__, cRetainerCalls, c - uBase); 150 g_cErrors++; 151 } 152 153 /* remove all the entries (in order) */ 154 RTPrintf("tstHandleTable: TESTING RTHandleTableFreeWithCtx.."); RTStrmFlush(g_pStdOut); 155 cRetainerCalls = 0; 156 for (i = 1; i < c; i++) 157 { 158 void *pvExpect = (void *)((uintptr_t)&i + (uintptr_t)i * 4); 159 void *pvObj = RTHandleTableFreeWithCtx(hHT, i, NULL); 160 if (!pvObj) 161 { 162 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableLookupWithCtx failed!\n", __LINE__, i); 163 g_cErrors++; 164 } 165 else if (pvObj != pvExpect) 166 { 167 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, pvObj=%p expected %p\n", __LINE__, i, pvObj, pvExpect); 168 g_cErrors++; 169 } 170 else if (RTHandleTableLookupWithCtx(hHT, i, NULL)) 171 { 172 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableLookupWithCtx succeeded after free!\n", __LINE__, i); 173 g_cErrors++; 174 } 175 if (!(i % cUnitsPerDot)) 176 { 177 RTPrintf("."); 178 RTStrmFlush(g_pStdOut); 179 } 180 } 181 RTPrintf("\n"); 182 if (fCallbacks && cRetainerCalls != c - uBase) 183 { 184 RTPrintf("tstHandleTable: FAILURE (%d) - cRetainerCalls=%#x expected %#x!\n", __LINE__, cRetainerCalls, c - uBase); 185 g_cErrors++; 186 } 187 188 /* do a mix of alloc, lookup and free where there is a constant of cDelta handles in the table. */ 189 RTPrintf("tstHandleTable: TESTING Alloc,Lookup,Free mix [cDelta=%#x]..", cDelta); RTStrmFlush(g_pStdOut); 190 for (i = 1; i < c * 2; i++) 191 { 192 /* alloc */ 193 uint32_t hExpect = ((i - 1) % (c - 1)) + 1; 194 uint32_t h; 195 rc = RTHandleTableAllocWithCtx(hHT, (void *)((uintptr_t)&i + (uintptr_t)hExpect * 4), NULL, &h); 196 if (RT_FAILURE(rc)) 197 { 198 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableAllocWithCtx: rc=%Rrc!\n", __LINE__, i, rc); 199 g_cErrors++; 200 } 201 else if (h != hExpect) 202 { 203 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableAllocWithCtx: rc=%Rrc!\n", __LINE__, i, rc); 204 g_cErrors++; 205 } 206 207 if (i > cDelta) 208 { 209 /* lookup */ 210 for (uint32_t j = i - cDelta; j <= i; j++) 211 { 212 uint32_t hLookup = ((j - 1) % (c - 1)) + 1; 213 void *pvExpect = (void *)((uintptr_t)&i + (uintptr_t)hLookup * 4); 214 void *pvObj = RTHandleTableLookupWithCtx(hHT, hLookup, NULL); 215 if (pvObj != pvExpect) 216 { 217 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, j=%d, RTHandleTableLookupWithCtx(,%u,): pvObj=%p expected %p!\n", 218 __LINE__, i, j, hLookup, pvObj, pvExpect); 219 g_cErrors++; 220 } 221 else if (RTHandleTableLookupWithCtx(hHT, hLookup, &i)) 222 { 223 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, j=%d, RTHandleTableLookupWithCtx: succeeded with bad context\n", 224 __LINE__, i, j, pvObj, pvExpect); 225 g_cErrors++; 226 } 227 } 228 229 /* free */ 230 uint32_t hFree = ((i - 1 - cDelta) % (c - 1)) + 1; 231 void *pvExpect = (void *)((uintptr_t)&i + (uintptr_t)hFree * 4); 232 void *pvObj = RTHandleTableFreeWithCtx(hHT, hFree, NULL); 233 if (pvObj != pvExpect) 234 { 235 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableFreeWithCtx: pvObj=%p expected %p!\n", 236 __LINE__, i, pvObj, pvExpect); 237 g_cErrors++; 238 } 239 else if ( RTHandleTableLookupWithCtx(hHT, hFree, NULL) 240 || RTHandleTableFreeWithCtx(hHT, hFree, NULL)) 241 { 242 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableLookup/FreeWithCtx: succeeded after free\n", 243 __LINE__, i); 244 g_cErrors++; 245 } 246 } 247 if (!(i % (cUnitsPerDot * 2))) 248 { 249 RTPrintf("."); 250 RTStrmFlush(g_pStdOut); 251 } 252 } 253 RTPrintf("\n"); 254 255 /* finally, destroy the table (note that there are 128 entries in it). */ 256 cRetainerCalls = 0; 257 uint32_t cDeleteCalls = 0; 258 rc = RTHandleTableDestroy(hHT, 259 fCallbacks ? tstHandleTableTest1Delete : NULL, 260 fCallbacks ? &cDeleteCalls : NULL); 261 if (RT_FAILURE(rc)) 262 { 263 RTPrintf("tstHandleTable: FAILURE (%d) - RTHandleTableDestroy failed, %Rrc!\n", __LINE__, rc); 264 g_cErrors++; 265 } 266 267 return 0; 268 } 269 270 int main(int argc, char **argv) 271 { 42 272 /* 43 * I f no args, display usage.273 * Init the runtime and parse the arguments. 44 274 */ 45 if (argc <= 1) 46 { 47 RTPrintf("Syntax: %s [so/dll [so/dll [..]]\n", argv[0]); 275 RTR3Init(false, 0); 276 277 static RTOPTIONDEF const s_aOptions[] = 278 { 279 { "--base", 'b', RTGETOPT_REQ_UINT32 }, 280 { "--max", 'm', RTGETOPT_REQ_UINT32 }, 281 }; 282 283 uint32_t uBase = 0; 284 uint32_t cMax = 0; 285 286 int ch; 287 int iArg = 1; 288 RTOPTIONUNION Value; 289 while ((ch = RTGetOpt(argc,argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), &iArg, &Value))) 290 switch (ch) 291 { 292 case 'b': 293 uBase = Value.u32; 294 break; 295 296 case 'm': 297 cMax = Value.u32; 298 break; 299 300 case '?': 301 case 'h': 302 RTPrintf("syntax: tstIntNet-1 [-pSt] [-d <secs>] [-f <file>] [-r <size>] [-s <size>]\n"); 303 return 1; 304 305 default: 306 if (RT_SUCCESS(ch)) 307 RTPrintf("tstHandleTable: invalid argument (%#x): %s\n", ch, Value.psz); 308 else 309 RTPrintf("tstHandleTable: invalid argument: %Rrc - \n", ch, Value.pDef->pszLong); 310 return 1; 311 } 312 if (iArg < argc) 313 { 314 RTPrintf("tstHandleTable: invalid argument: %s\n", argv[iArg]); 48 315 return 1; 49 316 } 50 317 51 318 /* 52 * Iterate the arguments and treat all of them as so/dll paths.319 * Do a simple warmup / smoke test first. 53 320 */ 54 for (int i = 1; i < argc; i++) 55 { 56 RTLDRMOD hLdrMod = (RTLDRMOD)0xbaadffaa; 57 int rc = RTLdrLoad(argv[i], &hLdrMod); 58 if (RT_SUCCESS(rc)) 59 { 60 RTPrintf("tstLdrLoad: %d - %s\n", i, argv[i]); 61 rc = RTLdrClose(hLdrMod); 62 if (RT_FAILURE(rc)) 63 { 64 RTPrintf("tstLdrLoad: rc=%Rrc RTLdrClose()\n", rc); 65 rcRet++; 66 } 67 } 68 else 69 { 70 RTPrintf("tstLdrLoad: rc=%Rrc RTLdrOpen('%s')\n", rc, argv[i]); 71 rcRet++; 72 } 73 } 321 /* these two are for the default case. */ 322 tstHandleTableTest1(0, 1, 65534, 128, 2048, false); 323 tstHandleTableTest1(RTHANDLETABLE_FLAGS_LOCKED, 1, 65534, 63, 2048, false); 324 /* Test that the retain and delete functions work. */ 325 tstHandleTableTest1(RTHANDLETABLE_FLAGS_LOCKED, 1, 1024, 256, 256, true); 326 /* For testing 1st level expansion / reallocation. */ 327 tstHandleTableTest1(0, 1, 1024*1024*8, 3, 150000, false); 328 329 /* 330 * Threaded tests. 331 */ 332 74 333 75 334 /* 76 335 * Summary. 77 336 */ 78 if (! rcRet)79 RTPrintf("tst LdrLoad: SUCCESS\n");337 if (!g_cErrors) 338 RTPrintf("tstHandleTable: SUCCESS\n"); 80 339 else 81 RTPrintf("tst LdrLoad: FAILURE - %d errors\n", rcRet);82 83 return !! rcRet;340 RTPrintf("tstHandleTable: FAILURE - %d errors\n", g_cErrors); 341 342 return !!g_cErrors; 84 343 }
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器