Bool MXUser_TryAcquireExclLock(MXUserExclLock *lock) // IN/OUT: { Bool success; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL); if (MXUserTryAcquireFail(lock->header.name)) { return FALSE; } success = MXRecLockTryAcquire(&lock->recursiveLock); if (success) { MXUserAcquisitionTracking(&lock->header, FALSE); if (vmx86_debug && (MXRecLockCount(&lock->recursiveLock) > 1)) { MXUserDumpAndPanic(&lock->header, "%s: Acquire on an acquired exclusive lock\n", __FUNCTION__); } } if (vmx86_stats) { MXUserStats *stats = Atomic_ReadPtr(&lock->statsMem); if (LIKELY(stats != NULL)) { MXUserAcquisitionSample(&stats->acquisitionStats, success, !success, 0ULL); } } return success; }
Bool MXUser_TryDownSemaphore(MXUserSemaphore *sema) // IN/OUT: { int err; Bool downOccurred = FALSE; ASSERT(sema); MXUserValidateHeader(&sema->header, MXUSER_TYPE_SEMA); Atomic_Inc(&sema->activeUserCount); err = MXUserTryDown(&sema->nativeSemaphore, &downOccurred); if (UNLIKELY(err != 0)) { MXUserDumpAndPanic(&sema->header, "%s: Internal error (%d)\n", __FUNCTION__, err); } if (vmx86_stats) { MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&sema->acquireStatsMem); if (LIKELY(acquireStats != NULL)) { MXUserAcquisitionSample(&acquireStats->data, downOccurred, !downOccurred, 0ULL); } } Atomic_Dec(&sema->activeUserCount); return downOccurred; }
void MXUser_DownSemaphore(MXUserSemaphore *sema) // IN/OUT: { int err; ASSERT(sema); MXUserValidateHeader(&sema->header, MXUSER_TYPE_SEMA); Atomic_Inc(&sema->activeUserCount); MXUserAcquisitionTracking(&sema->header, TRUE); // rank checking if (vmx86_stats) { VmTimeType start = 0; Bool tryDownSuccess = FALSE; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&sema->acquireStatsMem); if (LIKELY(acquireStats != NULL)) { start = Hostinfo_SystemTimerNS(); } err = MXUserTryDown(&sema->nativeSemaphore, &tryDownSuccess); if (LIKELY(err == 0)) { if (!tryDownSuccess) { err = MXUserDown(&sema->nativeSemaphore); } } if (LIKELY((err == 0) && (acquireStats != NULL))) { MXUserHisto *histo; VmTimeType value = Hostinfo_SystemTimerNS() - start; MXUserAcquisitionSample(&acquireStats->data, TRUE, !tryDownSuccess, value); histo = Atomic_ReadPtr(&acquireStats->histo); if (UNLIKELY(histo != NULL)) { MXUserHistoSample(histo, value, GetReturnAddress()); } } } else { err = MXUserDown(&sema->nativeSemaphore); } if (UNLIKELY(err != 0)) { MXUserDumpAndPanic(&sema->header, "%s: Internal error (%d)\n", __FUNCTION__, err); } MXUserReleaseTracking(&sema->header); Atomic_Dec(&sema->activeUserCount); }
void MXUser_AcquireRecLock(MXUserRecLock *lock) // IN/OUT: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); ASSERT(Atomic_Read(&lock->refCount) > 0); if (UNLIKELY(lock->vmmLock != NULL)) { ASSERT(MXUserMX_LockRec); (*MXUserMX_LockRec)(lock->vmmLock); } else { /* Rank checking is only done on the first acquisition */ MXUserAcquisitionTracking(&lock->header, TRUE); if (vmx86_stats) { VmTimeType value = 0; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); MXRecLockAcquire(&lock->recursiveLock, (acquireStats == NULL) ? NULL : &value); if (LIKELY(acquireStats != NULL)) { if (MXRecLockCount(&lock->recursiveLock) == 1) { MXUserHeldStats *heldStats; MXUserHisto *histo; MXUserAcquisitionSample(&acquireStats->data, TRUE, value > acquireStats->data.contentionDurationFloor, value); histo = Atomic_ReadPtr(&acquireStats->histo); if (UNLIKELY(histo != NULL)) { MXUserHistoSample(histo, value, GetReturnAddress()); } heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (UNLIKELY(heldStats != NULL)) { heldStats->holdStart = Hostinfo_SystemTimerNS(); } } } } else { MXRecLockAcquire(&lock->recursiveLock, NULL); // non-stats } } }
void MXUser_AcquireExclLock(MXUserExclLock *lock) // IN/OUT: { ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL); MXUserAcquisitionTracking(&lock->header, TRUE); if (vmx86_stats) { VmTimeType value = 0; MXUserStats *stats = Atomic_ReadPtr(&lock->statsMem); MXRecLockAcquire(&lock->recursiveLock, (stats == NULL) ? NULL : &value); if (LIKELY(stats != NULL)) { MXUserHisto *histo; MXUserAcquisitionSample(&stats->acquisitionStats, TRUE, value != 0, value); histo = Atomic_ReadPtr(&stats->acquisitionHisto); if (UNLIKELY(histo != NULL)) { MXUserHistoSample(histo, value, GetReturnAddress()); } stats->holdStart = Hostinfo_SystemTimerNS(); } } else { MXRecLockAcquire(&lock->recursiveLock, NULL); // non-stats } if (vmx86_debug && (MXRecLockCount(&lock->recursiveLock) > 1)) { MXUserDumpAndPanic(&lock->header, "%s: Acquire on an acquired exclusive lock\n", __FUNCTION__); } }
Bool MXUser_TryAcquireRecLock(MXUserRecLock *lock) // IN/OUT: { Bool success; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_REC); ASSERT(Atomic_Read(&lock->refCount) > 0); if (UNLIKELY(lock->vmmLock != NULL)) { ASSERT(MXUserMX_TryLockRec); success = (*MXUserMX_TryLockRec)(lock->vmmLock); } else { if (MXUserTryAcquireFail(lock->header.name)) { success = FALSE; goto bail; } success = MXRecLockTryAcquire(&lock->recursiveLock); if (success) { MXUserAcquisitionTracking(&lock->header, FALSE); } if (vmx86_stats) { MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (LIKELY(acquireStats != NULL)) { MXUserAcquisitionSample(&acquireStats->data, success, !success, 0ULL); } } } bail: return success; }
static INLINE void MXUserAcquisition(MXUserRWLock *lock, // IN/OUT: Bool forRead) // IN: { HolderContext *myContext; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_RW); MXUserAcquisitionTracking(&lock->header, TRUE); myContext = MXUserGetHolderContext(lock); if (UNLIKELY(myContext->state != RW_UNLOCKED)) { MXUserDumpAndPanic(&lock->header, "%s: AcquireFor%s after AcquireFor%s\n", __FUNCTION__, forRead ? "Read" : "Write", (myContext->state == RW_LOCKED_FOR_READ) ? "Read" : "Write"); } if (vmx86_stats) { VmTimeType value; MXUserStats *stats = Atomic_ReadPtr(&lock->statsMem); if (lock->useNative) { int err = 0; Bool contended; VmTimeType begin = Hostinfo_SystemTimerNS(); contended = MXUserNativeRWAcquire(&lock->nativeLock, forRead, &err); value = contended ? Hostinfo_SystemTimerNS() - begin : 0; if (UNLIKELY(err != 0)) { MXUserDumpAndPanic(&lock->header, "%s: Error %d: contended %d\n", __FUNCTION__, err, contended); } } else { value = 0; MXRecLockAcquire(&lock->recursiveLock, (stats == NULL) ? NULL : &value); } if (LIKELY(stats != NULL)) { MXUserHisto *histo; /* * The statistics are not atomically safe so protect them when * necessary. */ if (forRead && lock->useNative) { MXRecLockAcquire(&lock->recursiveLock, NULL); // non-stats } MXUserAcquisitionSample(&stats->acquisitionStats, TRUE, value != 0, value); histo = Atomic_ReadPtr(&stats->acquisitionHisto); if (UNLIKELY(histo != NULL)) { MXUserHistoSample(histo, value, GetReturnAddress()); } if (forRead && lock->useNative) { MXRecLockRelease(&lock->recursiveLock); } myContext->holdStart = Hostinfo_SystemTimerNS(); } } else { if (LIKELY(lock->useNative)) { int err = 0; MXUserNativeRWAcquire(&lock->nativeLock, forRead, &err); if (UNLIKELY(err != 0)) { MXUserDumpAndPanic(&lock->header, "%s: Error %d\n", __FUNCTION__, err); } } else { MXRecLockAcquire(&lock->recursiveLock, NULL); // non-stats } } if (!forRead || !lock->useNative) { ASSERT(Atomic_Read(&lock->holderCount) == 0); } Atomic_Inc(&lock->holderCount); myContext->state = forRead ? RW_LOCKED_FOR_READ : RW_LOCKED_FOR_WRITE; }