MXUserSemaphore * MXUser_CreateSemaphore(const char *userName, // IN: MX_Rank rank) // IN: { char *properName; MXUserSemaphore *sema; sema = Util_SafeCalloc(1, sizeof(*sema)); if (userName == NULL) { properName = Str_SafeAsprintf(NULL, "Sema-%p", GetReturnAddress()); } else { properName = Util_SafeStrdup(userName); } if (LIKELY(MXUserInit(&sema->nativeSemaphore) == 0)) { sema->header.signature = MXUserGetSignature(MXUSER_TYPE_SEMA); sema->header.name = properName; sema->header.rank = rank; sema->header.serialNumber = MXUserAllocSerialNumber(); sema->header.dumpFunc = MXUserDumpSemaphore; if (MXUserStatsMode() == 0) { sema->header.statsFunc = NULL; Atomic_WritePtr(&sema->acquireStatsMem, NULL); } else { MXUserAcquireStats *acquireStats; acquireStats = Util_SafeCalloc(1, sizeof(*acquireStats)); MXUserAcquisitionStatsSetUp(&acquireStats->data); sema->header.statsFunc = MXUserStatsActionSema; Atomic_WritePtr(&sema->acquireStatsMem, acquireStats); } MXUserAddToList(&sema->header); } else { free(properName); free(sema); sema = NULL; } return sema; }
Bool MXUser_ControlExclLock(MXUserExclLock *lock, // IN/OUT: uint32 command, // IN: ...) // IN: { Bool result; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_EXCL); switch (command) { case MXUSER_CONTROL_ACQUISITION_HISTO: { if (vmx86_stats) { MXUserStats *stats = Atomic_ReadPtr(&lock->statsMem); if (stats == NULL) { result = FALSE; } else { va_list a; uint32 decades; uint64 minValue; va_start(a, command); minValue = va_arg(a, uint64); decades = va_arg(a, uint32); va_end(a); MXUserForceHisto(&stats->acquisitionHisto, MXUSER_STAT_CLASS_ACQUISITION, minValue, decades); result = TRUE; } } else { result = FALSE; } break; } case MXUSER_CONTROL_HELD_HISTO: { if (vmx86_stats) { MXUserStats *stats = Atomic_ReadPtr(&lock->statsMem); if (stats == NULL) { result = FALSE; } else { va_list a; uint32 decades; uint32 minValue; va_start(a, command); minValue = va_arg(a, uint64); decades = va_arg(a, uint32); va_end(a); MXUserForceHisto(&stats->heldHisto, MXUSER_STAT_CLASS_HELD, minValue, decades); result = TRUE; } } else { result = FALSE; } break; } case MXUSER_CONTROL_ENABLE_STATS: { if (vmx86_stats) { MXUserStats *stats; MXUserStats *before; stats = Util_SafeCalloc(1, sizeof(*stats)); MXUserAcquisitionStatsSetUp(&stats->acquisitionStats); MXUserBasicStatsSetUp(&stats->heldStats, MXUSER_STAT_CLASS_HELD); before = Atomic_ReadIfEqualWritePtr(&lock->statsMem, NULL, (void *) stats); if (before) { free(stats); } lock->header.statsFunc = MXUserStatsActionExcl; result = TRUE; } else { result = FALSE; } break; } default: result = FALSE; } return result; }
Bool MXUser_ControlRWLock(MXUserRWLock *lock, // IN/OUT: uint32 command, // IN: ...) // IN: { Bool result; ASSERT(lock); MXUserValidateHeader(&lock->header, MXUSER_TYPE_RW); switch (command) { case MXUSER_CONTROL_ACQUISITION_HISTO: { if (vmx86_stats) { MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (acquireStats == NULL) { result = FALSE; } else { va_list a; uint32 decades; uint64 minValue; va_start(a, command); minValue = va_arg(a, uint64); decades = va_arg(a, uint32); va_end(a); MXUserForceHisto(&acquireStats->histo, MXUSER_STAT_CLASS_ACQUISITION, minValue, decades); result = TRUE; } } else { result = FALSE; } break; } case MXUSER_CONTROL_HELD_HISTO: { if (vmx86_stats) { MXUserHeldStats *heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if (heldStats == NULL) { result = FALSE; } else { va_list a; uint32 decades; uint32 minValue; va_start(a, command); minValue = va_arg(a, uint64); decades = va_arg(a, uint32); va_end(a); MXUserForceHisto(&heldStats->histo, MXUSER_STAT_CLASS_HELD, minValue, decades); result = TRUE; } } else { result = FALSE; } break; } case MXUSER_CONTROL_ENABLE_STATS: { if (vmx86_stats) { va_list a; Bool trackHeldTimes; MXUserHeldStats *heldStats; MXUserAcquireStats *acquireStats; acquireStats = Atomic_ReadPtr(&lock->acquireStatsMem); if (LIKELY(acquireStats == NULL)) { MXUserAcquireStats *before; acquireStats = Util_SafeCalloc(1, sizeof(*acquireStats)); MXUserAcquisitionStatsSetUp(&acquireStats->data); before = Atomic_ReadIfEqualWritePtr(&lock->acquireStatsMem, NULL, (void *) acquireStats); if (before) { free(acquireStats); } } va_start(a, command); trackHeldTimes = va_arg(a, int); va_end(a); heldStats = Atomic_ReadPtr(&lock->heldStatsMem); if ((heldStats == NULL) && trackHeldTimes) { MXUserHeldStats *before; heldStats = Util_SafeCalloc(1, sizeof(*heldStats)); MXUserBasicStatsSetUp(&heldStats->data, MXUSER_STAT_CLASS_HELD); before = Atomic_ReadIfEqualWritePtr(&lock->heldStatsMem, NULL, (void *) heldStats); if (before) { free(heldStats); } } lock->header.statsFunc = MXUserStatsActionRW; result = TRUE; } else { result = FALSE; } break; } default: result = FALSE; }