예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
/**
 * 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;
}
예제 #4
0
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;
}