static DECLCALLBACK(int) Test2Thread(RTTHREAD hThreadSelf, void *pvUser) { RTSEMRW hSemRW = (RTSEMRW)pvUser; RTTEST_CHECK_RC(g_hTest, RTSemRWRequestRead(hSemRW, 0), VERR_TIMEOUT); RTTEST_CHECK_RC(g_hTest, RTSemRWRequestWrite(hSemRW, 0), VERR_TIMEOUT); RTTEST_CHECK_RC(g_hTest, RTSemRWRequestRead(hSemRW, 1), VERR_TIMEOUT); RTTEST_CHECK_RC(g_hTest, RTSemRWRequestWrite(hSemRW, 1), VERR_TIMEOUT); RTTEST_CHECK_RC(g_hTest, RTSemRWRequestRead(hSemRW, 50), VERR_TIMEOUT); RTTEST_CHECK_RC(g_hTest, RTSemRWRequestWrite(hSemRW, 50), VERR_TIMEOUT); return VINF_SUCCESS; }
DECLINLINE(void) rtThreadLockRD(void) { if (g_ThreadRWSem == NIL_RTSEMRW) rtThreadInit(); int rc = RTSemRWRequestRead(g_ThreadRWSem, RT_INDEFINITE_WAIT); AssertReleaseRC(rc); }
static void Test3(void) { RTTestSub(g_hTest, "Negative"); bool fSavedAssertQuiet = RTAssertSetQuiet(true); bool fSavedAssertMayPanic = RTAssertSetMayPanic(false); bool fSavedLckValEnabled = RTLockValidatorSetEnabled(false); RTSEMRW hSemRW; RTTEST_CHECK_RC_RETV(g_hTest, RTSemRWCreate(&hSemRW), VINF_SUCCESS); RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead(hSemRW), VERR_NOT_OWNER); RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(hSemRW), VERR_NOT_OWNER); RTTEST_CHECK_RC(g_hTest, RTSemRWRequestWrite(hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS); RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead(hSemRW), VERR_NOT_OWNER); RTTEST_CHECK_RC(g_hTest, RTSemRWRequestRead(hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS); RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(hSemRW), VERR_WRONG_ORDER); /* cannot release the final write before the reads. */ RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseRead(hSemRW), VINF_SUCCESS); RTTEST_CHECK_RC(g_hTest, RTSemRWReleaseWrite(hSemRW), VINF_SUCCESS); RTTEST_CHECK_RC(g_hTest, RTSemRWDestroy(hSemRW), VINF_SUCCESS); RTLockValidatorSetEnabled(fSavedLckValEnabled); RTAssertSetMayPanic(fSavedAssertMayPanic); RTAssertSetQuiet(fSavedAssertQuiet); }
/*virtual*/ void RWLockHandle::lockRead(LOCKVAL_SRC_POS_DECL) { #ifdef GLUE_USE_CRITSECTRW # ifdef VBOX_WITH_MAIN_LOCK_VALIDATION int vrc = RTCritSectRwEnterSharedDebug(&m->CritSect, (uintptr_t)ASMReturnAddress(), RT_SRC_POS_ARGS); # else int vrc = RTCritSectRwEnterShared(&m->CritSect); # endif #else # ifdef VBOX_WITH_MAIN_LOCK_VALIDATION int vrc = RTSemRWRequestReadDebug(m->sem, RT_INDEFINITE_WAIT, (uintptr_t)ASMReturnAddress(), RT_SRC_POS_ARGS); # else int vrc = RTSemRWRequestRead(m->sem, RT_INDEFINITE_WAIT); # endif #endif AssertRC(vrc); }
static bool Test1(void) { RTTestSub(g_hTest, "Basics"); RTSEMRW hSemRW = NIL_RTSEMRW; RTTEST_CHECK_RC_RET(g_hTest, RTSemRWCreate(&hSemRW), VINF_SUCCESS, false); RTTEST_CHECK_RET(g_hTest, hSemRW != NIL_RTSEMRW, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestRead(hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseRead(hSemRW), VINF_SUCCESS, false); for (unsigned cMs = 0; cMs < 50; cMs++) { RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestRead(hSemRW, cMs), VINF_SUCCESS, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestRead(hSemRW, cMs), VINF_SUCCESS, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseRead(hSemRW), VINF_SUCCESS, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseRead(hSemRW), VINF_SUCCESS, false); } RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestWrite(hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseWrite(hSemRW), VINF_SUCCESS, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestWrite(hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestRead(hSemRW, RT_INDEFINITE_WAIT), VINF_SUCCESS, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseRead(hSemRW), VINF_SUCCESS, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseWrite(hSemRW), VINF_SUCCESS, false); for (unsigned cMs = 0; cMs < 50; cMs++) { RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestWrite(hSemRW, cMs), VINF_SUCCESS, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 1, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 0, false); RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestWrite(hSemRW, cMs), VINF_SUCCESS, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 2, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 0, false); RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestRead(hSemRW, cMs), VINF_SUCCESS, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 2, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 1, false); RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWRequestWrite(hSemRW, cMs), VINF_SUCCESS, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 3, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 1, false); RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false); /* midway */ RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseWrite(hSemRW), VINF_SUCCESS, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 2, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 1, false); RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseRead(hSemRW), VINF_SUCCESS, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 2, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 0, false); RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseWrite(hSemRW), VINF_SUCCESS, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 1, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 0, false); RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == true, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWReleaseWrite(hSemRW), VINF_SUCCESS, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriteRecursion(hSemRW) == 0, false); RTTEST_CHECK_RET(g_hTest, RTSemRWGetWriterReadRecursion(hSemRW) == 0, false); RTTEST_CHECK_RET(g_hTest, RTSemRWIsWriteOwner(hSemRW) == false, false); } RTTEST_CHECK_RC_RET(g_hTest, RTSemRWDestroy(hSemRW), VINF_SUCCESS, false); RTTEST_CHECK_RC_RET(g_hTest, RTSemRWDestroy(NIL_RTSEMRW), VINF_SUCCESS, false); return true; }
RTDECL(int) RTDbgModCreateFromMap(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, RTUINTPTR uSubtrahend, uint32_t fFlags) { /* * Input validation and lazy initialization. */ AssertPtrReturn(phDbgMod, VERR_INVALID_POINTER); *phDbgMod = NIL_RTDBGMOD; AssertPtrReturn(pszFilename, VERR_INVALID_POINTER); AssertReturn(*pszFilename, VERR_INVALID_PARAMETER); AssertPtrNullReturn(pszName, VERR_INVALID_POINTER); AssertReturn(fFlags == 0, VERR_INVALID_PARAMETER); int rc = rtDbgModLazyInit(); if (RT_FAILURE(rc)) return rc; if (!pszName) pszName = RTPathFilename(pszFilename); /* * Allocate a new module instance. */ PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod)); if (!pDbgMod) return VERR_NO_MEMORY; pDbgMod->u32Magic = RTDBGMOD_MAGIC; pDbgMod->cRefs = 1; rc = RTCritSectInit(&pDbgMod->CritSect); if (RT_SUCCESS(rc)) { pDbgMod->pszName = RTStrCacheEnter(g_hDbgModStrCache, pszName); if (pDbgMod->pszName) { pDbgMod->pszDbgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename); if (pDbgMod->pszDbgFile) { /* * Try the map file readers. */ rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT); if (RT_SUCCESS(rc)) { rc = VERR_DBG_NO_MATCHING_INTERPRETER; for (PRTDBGMODREGDBG pCur = g_pDbgHead; pCur; pCur = pCur->pNext) { if (pCur->pVt->fSupports & RT_DBGTYPE_MAP) { pDbgMod->pDbgVt = pCur->pVt; pDbgMod->pvDbgPriv = NULL; rc = pCur->pVt->pfnTryOpen(pDbgMod); if (RT_SUCCESS(rc)) { ASMAtomicIncU32(&pCur->cUsers); RTSemRWReleaseRead(g_hDbgModRWSem); *phDbgMod = pDbgMod; return rc; } } } /* bail out */ RTSemRWReleaseRead(g_hDbgModRWSem); } RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName); } RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile); } RTCritSectDelete(&pDbgMod->CritSect); } RTMemFree(pDbgMod); return rc; }