static void pdmNsBwGroupXmitPending(PPDMNSBWGROUP pBwGroup) { /* * We don't need to hold the bandwidth group lock to iterate over the list * of filters since the filters are removed while the shaper lock is being * held. */ AssertPtr(pBwGroup); AssertPtr(pBwGroup->pShaper); Assert(RTCritSectIsOwner(&pBwGroup->pShaper->cs)); //int rc = RTCritSectEnter(&pBwGroup->cs); AssertRC(rc); /* Check if the group is disabled. */ if (pBwGroup->cbTransferPerSecMax == 0) return; PPDMNSFILTER pFilter = pBwGroup->pFiltersHead; while (pFilter) { bool fChoked = ASMAtomicXchgBool(&pFilter->fChoked, false); Log3((LOG_FN_FMT ": pFilter=%#p fChoked=%RTbool\n", __PRETTY_FUNCTION__, pFilter, fChoked)); if (fChoked && pFilter->pIDrvNet) { LogFlowFunc(("Calling pfnXmitPending for pFilter=%#p\n", pFilter)); pFilter->pIDrvNet->pfnXmitPending(pFilter->pIDrvNet); } pFilter = pFilter->pNext; } //rc = RTCritSectLeave(&pBwGroup->cs); AssertRC(rc); }
static void pdmNsFilterUnlink(PPDMNSFILTER pFilter) { PPDMNSBWGROUP pBwGroup = pFilter->pBwGroupR3; /* * We need to make sure we hold the shaper lock since pdmNsBwGroupXmitPending() * does not hold the bandwidth group lock while iterating over the list * of group's filters. */ AssertPtr(pBwGroup); AssertPtr(pBwGroup->pShaper); Assert(RTCritSectIsOwner(&pBwGroup->pShaper->cs)); int rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc); if (pFilter == pBwGroup->pFiltersHead) pBwGroup->pFiltersHead = pFilter->pNext; else { PPDMNSFILTER pPrev = pBwGroup->pFiltersHead; while ( pPrev && pPrev->pNext != pFilter) pPrev = pPrev->pNext; AssertPtr(pPrev); pPrev->pNext = pFilter->pNext; } rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc); }
/** * Decrements the VBoxSVC client count. */ void VirtualBoxSDS::i_decrementClientCount() { Assert(RTCritSectIsOwner(&m_WatcherCritSect)); uint32_t cClients = --m_cVBoxSvcProcesses; Assert(cClients < 4096); VBoxSDSNotifyClientCount(cClients); }
/** * Checks the specified VCPU is the owner of the critical section. * * @returns true if owner. * @returns false if not owner. * @param pCritSect The critical section. * @param pVCpu The virtual CPU handle. */ VMMDECL(bool) PDMCritSectIsOwnerEx(PCPDMCRITSECT pCritSect, PVMCPU pVCpu) { #ifdef IN_RING3 NOREF(pVCpu); return RTCritSectIsOwner(&pCritSect->s.Core); #else Assert(&pVCpu->CTX_SUFF(pVM)->aCpus[pVCpu->idCpu] == pVCpu); if (pCritSect->s.Core.NativeThreadOwner != pVCpu->hNativeThread) return false; return (pCritSect->s.Core.fFlags & PDMCRITSECT_FLAGS_PENDING_UNLOCK) == 0 || pCritSect->s.Core.cNestings > 1; #endif }
/** * Checks the caller is the owner of the critical section. * * @returns true if owner. * @returns false if not owner. * @param pCritSect The critical section. */ VMMDECL(bool) PDMCritSectIsOwner(PCPDMCRITSECT pCritSect) { #ifdef IN_RING3 return RTCritSectIsOwner(&pCritSect->s.Core); #else PVM pVM = pCritSect->s.CTX_SUFF(pVM); AssertPtr(pVM); PVMCPU pVCpu = VMMGetCpu(pVM); AssertPtr(pVCpu); if (pCritSect->s.Core.NativeThreadOwner != pVCpu->hNativeThread) return false; return (pCritSect->s.Core.fFlags & PDMCRITSECT_FLAGS_PENDING_UNLOCK) == 0 || pCritSect->s.Core.cNestings > 1; #endif }
/** * 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; }
/** * Schedule a event semaphore for signalling upon critsect exit. * * @returns VINF_SUCCESS on success. * @returns VERR_TOO_MANY_SEMAPHORES if an event was already scheduled. * @returns VERR_NOT_OWNER if we're not the critsect owner. * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. * * @param pCritSect The critical section. * @param EventToSignal The semaphore that should be signalled. */ VMMR3DECL(int) PDMR3CritSectScheduleExitEvent(PPDMCRITSECT pCritSect, RTSEMEVENT EventToSignal) { AssertPtr(pCritSect); Assert(!(pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NOP)); Assert(EventToSignal != NIL_RTSEMEVENT); if (RT_UNLIKELY(!RTCritSectIsOwner(&pCritSect->s.Core))) return VERR_NOT_OWNER; if (RT_LIKELY( pCritSect->s.EventToSignal == NIL_RTSEMEVENT || pCritSect->s.EventToSignal == EventToSignal)) { pCritSect->s.EventToSignal = EventToSignal; return VINF_SUCCESS; } return VERR_TOO_MANY_SEMAPHORES; }
/** * Schedule a event semaphore for signalling upon critsect exit. * * @returns VINF_SUCCESS on success. * @returns VERR_TOO_MANY_SEMAPHORES if an event was already scheduled. * @returns VERR_NOT_OWNER if we're not the critsect owner (ring-3 only). * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. * * @param pCritSect The critical section. * @param hEventToSignal The support driver event semaphore that should be * signalled. */ VMMDECL(int) PDMHCCritSectScheduleExitEvent(PPDMCRITSECT pCritSect, SUPSEMEVENT hEventToSignal) { AssertPtr(pCritSect); Assert(!(pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NOP)); Assert(hEventToSignal != NIL_SUPSEMEVENT); # ifdef IN_RING3 if (RT_UNLIKELY(!RTCritSectIsOwner(&pCritSect->s.Core))) return VERR_NOT_OWNER; # endif if (RT_LIKELY( pCritSect->s.hEventToSignal == NIL_RTSEMEVENT || pCritSect->s.hEventToSignal == hEventToSignal)) { pCritSect->s.hEventToSignal = hEventToSignal; return VINF_SUCCESS; } return VERR_TOO_MANY_SEMAPHORES; }
/*virtual*/ bool WriteLockHandle::isWriteLockOnCurrentThread() const { return RTCritSectIsOwner(&m->sem); }