RTDECL(int) RTCritSectDelete(PRTCRITSECT pCritSect) { /* * Assert free waiters and so on. */ Assert(pCritSect); Assert(pCritSect->u32Magic == RTCRITSECT_MAGIC); Assert(pCritSect->cNestings == 0); Assert(pCritSect->cLockers == -1); Assert(pCritSect->NativeThreadOwner == NIL_RTNATIVETHREAD); /* * Invalidate the structure and free the mutex. * In case someone is waiting we'll signal the semaphore cLockers + 1 times. */ ASMAtomicWriteU32(&pCritSect->u32Magic, ~RTCRITSECT_MAGIC); pCritSect->fFlags = 0; pCritSect->cNestings = 0; pCritSect->NativeThreadOwner= NIL_RTNATIVETHREAD; RTSEMEVENT EventSem = pCritSect->EventSem; pCritSect->EventSem = NIL_RTSEMEVENT; while (pCritSect->cLockers-- >= 0) RTSemEventSignal(EventSem); ASMAtomicWriteS32(&pCritSect->cLockers, -1); int rc = RTSemEventDestroy(EventSem); AssertRC(rc); RTLockValidatorRecExclDestroy(&pCritSect->pValidatorRec); return rc; }
RTDECL(int) RTCritSectInitEx(PRTCRITSECT pCritSect, uint32_t fFlags, RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...) { AssertReturn(!(fFlags & ~(RTCRITSECT_FLAGS_NO_NESTING | RTCRITSECT_FLAGS_NO_LOCK_VAL | RTCRITSECT_FLAGS_BOOTSTRAP_HACK | RTCRITSECT_FLAGS_NOP)), VERR_INVALID_PARAMETER); /* * Initialize the structure and */ pCritSect->u32Magic = RTCRITSECT_MAGIC; pCritSect->fFlags = fFlags; pCritSect->cNestings = 0; pCritSect->cLockers = -1; pCritSect->NativeThreadOwner = NIL_RTNATIVETHREAD; pCritSect->pValidatorRec = NULL; int rc = VINF_SUCCESS; #ifdef RTCRITSECT_STRICT if (!(fFlags & (RTCRITSECT_FLAGS_BOOTSTRAP_HACK | RTCRITSECT_FLAGS_NOP))) { if (!pszNameFmt) { static uint32_t volatile s_iCritSectAnon = 0; rc = RTLockValidatorRecExclCreate(&pCritSect->pValidatorRec, hClass, uSubClass, pCritSect, !(fFlags & RTCRITSECT_FLAGS_NO_LOCK_VAL), "RTCritSect-%u", ASMAtomicIncU32(&s_iCritSectAnon) - 1); } else { va_list va; va_start(va, pszNameFmt); rc = RTLockValidatorRecExclCreateV(&pCritSect->pValidatorRec, hClass, uSubClass, pCritSect, !(fFlags & RTCRITSECT_FLAGS_NO_LOCK_VAL), pszNameFmt, va); va_end(va); } } #endif if (RT_SUCCESS(rc)) { rc = RTSemEventCreateEx(&pCritSect->EventSem, fFlags & RTCRITSECT_FLAGS_BOOTSTRAP_HACK ? RTSEMEVENT_FLAGS_NO_LOCK_VAL | RTSEMEVENT_FLAGS_BOOTSTRAP_HACK : RTSEMEVENT_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, NULL); if (RT_SUCCESS(rc)) return VINF_SUCCESS; RTLockValidatorRecExclDestroy(&pCritSect->pValidatorRec); } AssertRC(rc); pCritSect->EventSem = NULL; pCritSect->u32Magic = (uint32_t)rc; return rc; }
/** * Deletes one critical section. * * @returns Return code from RTCritSectDelete. * * @param pVM Pointer to the VM. * @param pCritSect The critical section. * @param pPrev The previous critical section in the list. * @param fFinal Set if this is the final call and statistics shouldn't be deregistered. * * @remarks Caller must have entered the ListCritSect. */ static int pdmR3CritSectDeleteOne(PVM pVM, PUVM pUVM, PPDMCRITSECTINT pCritSect, PPDMCRITSECTINT pPrev, bool fFinal) { /* * Assert free waiters and so on (c&p from RTCritSectDelete). */ Assert(pCritSect->Core.u32Magic == RTCRITSECT_MAGIC); Assert(pCritSect->Core.cNestings == 0); Assert(pCritSect->Core.cLockers == -1); Assert(pCritSect->Core.NativeThreadOwner == NIL_RTNATIVETHREAD); Assert(RTCritSectIsOwner(&pUVM->pdm.s.ListCritSect)); /* * Unlink it. */ if (pPrev) pPrev->pNext = pCritSect->pNext; else pUVM->pdm.s.pCritSects = pCritSect->pNext; /* * Delete it (parts taken from RTCritSectDelete). * In case someone is waiting we'll signal the semaphore cLockers + 1 times. */ ASMAtomicWriteU32(&pCritSect->Core.u32Magic, 0); SUPSEMEVENT hEvent = (SUPSEMEVENT)pCritSect->Core.EventSem; pCritSect->Core.EventSem = NIL_RTSEMEVENT; while (pCritSect->Core.cLockers-- >= 0) SUPSemEventSignal(pVM->pSession, hEvent); ASMAtomicWriteS32(&pCritSect->Core.cLockers, -1); int rc = SUPSemEventClose(pVM->pSession, hEvent); AssertRC(rc); RTLockValidatorRecExclDestroy(&pCritSect->Core.pValidatorRec); pCritSect->pNext = NULL; pCritSect->pvKey = NULL; pCritSect->pVMR3 = NULL; pCritSect->pVMR0 = NIL_RTR0PTR; pCritSect->pVMRC = NIL_RTRCPTR; RTStrFree((char *)pCritSect->pszName); pCritSect->pszName = NULL; if (!fFinal) { STAMR3Deregister(pVM, &pCritSect->StatContentionRZLock); STAMR3Deregister(pVM, &pCritSect->StatContentionRZUnlock); STAMR3Deregister(pVM, &pCritSect->StatContentionR3); #ifdef VBOX_WITH_STATISTICS STAMR3Deregister(pVM, &pCritSect->StatLocked); #endif } return rc; }
RTDECL(int) RTCritSectRwInitEx(PRTCRITSECTRW pThis, uint32_t fFlags, RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...) { int rc; AssertReturn(!(fFlags & ~( RTCRITSECT_FLAGS_NO_NESTING | RTCRITSECT_FLAGS_NO_LOCK_VAL | RTCRITSECT_FLAGS_BOOTSTRAP_HACK | RTCRITSECT_FLAGS_NOP )), VERR_INVALID_PARAMETER); /* * Initialize the structure, allocate the lock validator stuff and sems. */ pThis->u32Magic = RTCRITSECTRW_MAGIC_DEAD; pThis->fNeedReset = false; #ifdef IN_RING0 pThis->fFlags = (uint16_t)(fFlags | RTCRITSECT_FLAGS_RING0); #else pThis->fFlags = (uint16_t)(fFlags & ~RTCRITSECT_FLAGS_RING0); #endif pThis->u64State = 0; pThis->hNativeWriter = NIL_RTNATIVETHREAD; pThis->cWriterReads = 0; pThis->cWriteRecursions = 0; pThis->hEvtWrite = NIL_RTSEMEVENT; pThis->hEvtRead = NIL_RTSEMEVENTMULTI; pThis->pValidatorWrite = NULL; pThis->pValidatorRead = NULL; #if HC_ARCH_BITS == 32 pThis->HCPtrPadding = NIL_RTHCPTR; #endif #ifdef RTCRITSECTRW_STRICT bool const fLVEnabled = !(fFlags & RTCRITSECT_FLAGS_NO_LOCK_VAL); if (!pszNameFmt) { static uint32_t volatile s_iAnon = 0; uint32_t i = ASMAtomicIncU32(&s_iAnon) - 1; rc = RTLockValidatorRecExclCreate(&pThis->pValidatorWrite, hClass, uSubClass, pThis, fLVEnabled, "RTCritSectRw-%u", i); if (RT_SUCCESS(rc)) rc = RTLockValidatorRecSharedCreate(&pThis->pValidatorRead, hClass, uSubClass, pThis, false /*fSignaller*/, fLVEnabled, "RTCritSectRw-%u", i); } else { va_list va; va_start(va, pszNameFmt); rc = RTLockValidatorRecExclCreateV(&pThis->pValidatorWrite, hClass, uSubClass, pThis, fLVEnabled, pszNameFmt, va); va_end(va); if (RT_SUCCESS(rc)) { va_start(va, pszNameFmt); RTLockValidatorRecSharedCreateV(&pThis->pValidatorRead, hClass, uSubClass, pThis, false /*fSignaller*/, fLVEnabled, pszNameFmt, va); va_end(va); } } if (RT_SUCCESS(rc)) rc = RTLockValidatorRecMakeSiblings(&pThis->pValidatorWrite->Core, &pThis->pValidatorRead->Core); if (RT_SUCCESS(rc)) #endif { rc = RTSemEventMultiCreate(&pThis->hEvtRead); if (RT_SUCCESS(rc)) { rc = RTSemEventCreate(&pThis->hEvtWrite); if (RT_SUCCESS(rc)) { pThis->u32Magic = RTCRITSECTRW_MAGIC; return VINF_SUCCESS; } RTSemEventMultiDestroy(pThis->hEvtRead); } } #ifdef RTCRITSECTRW_STRICT RTLockValidatorRecSharedDestroy(&pThis->pValidatorRead); RTLockValidatorRecExclDestroy(&pThis->pValidatorWrite); #endif return rc; }