static int supR0SemEventMultiWaitEx(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t fFlags, uint64_t uTimeout) { int rc; uint32_t h32; PSUPDRVOBJ pObj; /* * Input validation. */ AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER); h32 = (uint32_t)(uintptr_t)hEventMulti; if (h32 != (uintptr_t)hEventMulti) return VERR_INVALID_HANDLE; pObj = (PSUPDRVOBJ)RTHandleTableLookupWithCtx(pSession->hHandleTable, h32, SUPDRV_HANDLE_CTX_EVENT_MULTI); if (!pObj) return VERR_INVALID_HANDLE; /* * Do the job. */ rc = RTSemEventMultiWaitEx((RTSEMEVENTMULTI)pObj->pvUser1, fFlags, uTimeout); SUPR0ObjRelease(pObj, pSession); return rc; }
SUPDECL(int) SUPSemEventSignal(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent) { int rc; uint32_t h32; PSUPDRVOBJ pObj; /* * Input validation. */ AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER); h32 = (uint32_t)(uintptr_t)hEvent; if (h32 != (uintptr_t)hEvent) return VERR_INVALID_HANDLE; pObj = (PSUPDRVOBJ)RTHandleTableLookupWithCtx(pSession->hHandleTable, h32, SUPDRV_HANDLE_CTX_EVENT); if (!pObj) return VERR_INVALID_HANDLE; /* * Do the job. */ rc = RTSemEventSignal((RTSEMEVENT)pObj->pvUser1); SUPR0ObjRelease(pObj, pSession); return rc; }
static int tstHandleTableTest1(uint32_t uBase, uint32_t cMax, uint32_t cDelta, uint32_t cUnitsPerDot, bool fCallbacks, uint32_t fFlags) { const char *pszWithCtx = fFlags & RTHANDLETABLE_FLAGS_CONTEXT ? "WithCtx" : ""; uint32_t cRetainerCalls = 0; int rc; RTPrintf("tstHandleTable: TESTING RTHandleTableCreateEx(, 0"); if (fFlags & RTHANDLETABLE_FLAGS_LOCKED) RTPrintf(" | LOCKED"); if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT) RTPrintf(" | CONTEXT"); RTPrintf(", %#x, %#x,,)...\n", uBase, cMax); RTHANDLETABLE hHT; rc = RTHandleTableCreateEx(&hHT, fFlags, uBase, cMax, fCallbacks ? tstHandleTableTest1Retain : NULL, fCallbacks ? &cRetainerCalls : NULL); if (RT_FAILURE(rc)) { RTPrintf("\ntstHandleTable: FAILURE - RTHandleTableCreateEx failed, %Rrc!\n", rc); return 1; } /* fill it */ RTPrintf("tstHandleTable: TESTING RTHandleTableAlloc%s..", pszWithCtx); RTStrmFlush(g_pStdOut); uint32_t i = uBase; for (;; i++) { uint32_t h; if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT) rc = RTHandleTableAllocWithCtx(hHT, (void *)((uintptr_t)&i + (uintptr_t)i * 4), NULL, &h); else rc = RTHandleTableAlloc(hHT, (void *)((uintptr_t)&i + (uintptr_t)i * 4), &h); if (RT_SUCCESS(rc)) { if (h != i) { RTPrintf("\ntstHandleTable: FAILURE (%d) - h=%d, expected %d!\n", __LINE__, h, i); g_cErrors++; } } else if (rc == VERR_NO_MORE_HANDLES) { if (i < cMax) { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, expected > 65534!\n", __LINE__, i); g_cErrors++; } break; } else { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, rc=%Rrc!\n", __LINE__, i, rc); g_cErrors++; } if (!(i % cUnitsPerDot)) { RTPrintf("."); RTStrmFlush(g_pStdOut); } } uint32_t const c = i; RTPrintf(" c=%#x\n", c); if (fCallbacks && cRetainerCalls != 0) { RTPrintf("tstHandleTable: FAILURE (%d) - cRetainerCalls=%#x expected 0!\n", __LINE__, cRetainerCalls); g_cErrors++; } /* look up all the entries */ RTPrintf("tstHandleTable: TESTING RTHandleTableLookup%s..", pszWithCtx); RTStrmFlush(g_pStdOut); cRetainerCalls = 0; for (i = uBase; i < c; i++) { void *pvExpect = (void *)((uintptr_t)&i + (uintptr_t)i * 4); void *pvObj; if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT) pvObj = RTHandleTableLookupWithCtx(hHT, i, NULL); else pvObj = RTHandleTableLookup(hHT, i); if (!pvObj) { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableLookup%s failed!\n", __LINE__, i, pszWithCtx); g_cErrors++; } else if (pvObj != pvExpect) { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, pvObj=%p expected %p\n", __LINE__, i, pvObj, pvExpect); g_cErrors++; } if (!(i % cUnitsPerDot)) { RTPrintf("."); RTStrmFlush(g_pStdOut); } } RTPrintf("\n"); if (fCallbacks && cRetainerCalls != c - uBase) { RTPrintf("tstHandleTable: FAILURE (%d) - cRetainerCalls=%#x expected %#x!\n", __LINE__, cRetainerCalls, c - uBase); g_cErrors++; } /* remove all the entries (in order) */ RTPrintf("tstHandleTable: TESTING RTHandleTableFree%s..", pszWithCtx); RTStrmFlush(g_pStdOut); cRetainerCalls = 0; for (i = uBase; i < c; i++) { void *pvExpect = (void *)((uintptr_t)&i + (uintptr_t)i * 4); void *pvObj; if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT) pvObj = RTHandleTableFreeWithCtx(hHT, i, NULL); else pvObj = RTHandleTableFree(hHT, i); if (!pvObj) { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableLookup%s failed!\n", __LINE__, i, pszWithCtx); g_cErrors++; } else if (pvObj != pvExpect) { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, pvObj=%p expected %p\n", __LINE__, i, pvObj, pvExpect); g_cErrors++; } else if ( fFlags & RTHANDLETABLE_FLAGS_CONTEXT ? RTHandleTableLookupWithCtx(hHT, i, NULL) : RTHandleTableLookup(hHT, i)) { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableLookup%s succeeded after free!\n", __LINE__, i, pszWithCtx); g_cErrors++; } if (!(i % cUnitsPerDot)) { RTPrintf("."); RTStrmFlush(g_pStdOut); } } RTPrintf("\n"); if (fCallbacks && cRetainerCalls != c - uBase) { RTPrintf("tstHandleTable: FAILURE (%d) - cRetainerCalls=%#x expected %#x!\n", __LINE__, cRetainerCalls, c - uBase); g_cErrors++; } /* do a mix of alloc, lookup and free where there is a constant of cDelta handles in the table. */ RTPrintf("tstHandleTable: TESTING Alloc,Lookup,Free mix [cDelta=%#x]..", cDelta); RTStrmFlush(g_pStdOut); for (i = uBase; i < c * 2; i++) { /* alloc */ uint32_t hExpect = ((i - uBase) % (c - uBase)) + uBase; uint32_t h; if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT) rc = RTHandleTableAllocWithCtx(hHT, (void *)((uintptr_t)&i + (uintptr_t)hExpect * 4), NULL, &h); else rc = RTHandleTableAlloc(hHT, (void *)((uintptr_t)&i + (uintptr_t)hExpect * 4), &h); if (RT_FAILURE(rc)) { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableAlloc%s: rc=%Rrc!\n", __LINE__, i, pszWithCtx, rc); g_cErrors++; } else if (h != hExpect) { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableAlloc%s: h=%u hExpect=%u! - abort sub-test\n", __LINE__, i, pszWithCtx, h, hExpect); g_cErrors++; break; } if (i >= cDelta + uBase) { /* lookup */ for (uint32_t j = i - cDelta; j <= i; j++) { uint32_t hLookup = ((j - uBase) % (c - uBase)) + uBase; void *pvExpect = (void *)((uintptr_t)&i + (uintptr_t)hLookup * 4); void *pvObj; if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT) pvObj = RTHandleTableLookupWithCtx(hHT, hLookup, NULL); else pvObj = RTHandleTableLookup(hHT, hLookup); if (pvObj != pvExpect) { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, j=%d, RTHandleTableLookup%s(,%u,): pvObj=%p expected %p!\n", __LINE__, i, j, pszWithCtx, hLookup, pvObj, pvExpect); g_cErrors++; } else if ( (fFlags & RTHANDLETABLE_FLAGS_CONTEXT) && RTHandleTableLookupWithCtx(hHT, hLookup, &i)) { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, j=%d, RTHandleTableLookupWithCtx: succeeded with bad context\n", __LINE__, i, j); g_cErrors++; } } /* free */ uint32_t hFree = ((i - uBase - cDelta) % (c - uBase)) + uBase; void *pvExpect = (void *)((uintptr_t)&i + (uintptr_t)hFree * 4); void *pvObj; if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT) pvObj = RTHandleTableFreeWithCtx(hHT, hFree, NULL); else pvObj = RTHandleTableFree(hHT, hFree); if (pvObj != pvExpect) { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableFree%s: pvObj=%p expected %p!\n", __LINE__, i, pszWithCtx, pvObj, pvExpect); g_cErrors++; } else if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT ? RTHandleTableLookupWithCtx(hHT, hFree, NULL) || RTHandleTableFreeWithCtx(hHT, hFree, NULL) : RTHandleTableLookup(hHT, hFree) || RTHandleTableFree(hHT, hFree)) { RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableLookup/Free%s: succeeded after free\n", __LINE__, i, pszWithCtx); g_cErrors++; } } if (!(i % (cUnitsPerDot * 2))) { RTPrintf("."); RTStrmFlush(g_pStdOut); } } RTPrintf("\n"); /* finally, destroy the table (note that there are 128 entries in it). */ cRetainerCalls = 0; uint32_t cDeleteCalls = 0; rc = RTHandleTableDestroy(hHT, fCallbacks ? tstHandleTableTest1Delete : NULL, fCallbacks ? &cDeleteCalls : NULL); if (RT_FAILURE(rc)) { RTPrintf("tstHandleTable: FAILURE (%d) - RTHandleTableDestroy failed, %Rrc!\n", __LINE__, rc); g_cErrors++; } return 0; }