const char *name,
MX_Rank rank);
+Bool MXUser_ControlRWLock(MXUserRWLock *lock,
+ uint32 command,
+ ...);
+
/*
* Computational barrier
*/
void MXUser_DestroyCondVar(MXUserCondVar *condVar);
/*
- * MXUser_Control[Excl, Rec] commands
+ * MXUser_Control[Excl, Rec, RW] commands
*/
#define MXUSER_CONTROL_ACQUISITION_HISTO 0 // minValue, decades
#define MXUSER_CONTROL_HELD_HISTO 1 // minValue, decades
+#define MXUSER_CONTROL_ENABLE_STATS 2 // no arguments
#define MXUSER_DEFAULT_HISTO_MIN_VALUE_NS 1000 // 1 usec
#define MXUSER_DEFAULT_HISTO_DECADES 7 // 1 usec to 10 seconds
break;
}
+ case MXUSER_CONTROL_ENABLE_STATS: {
+ MXUserStats *stats = (MXUserStats *) Atomic_ReadPtr(&lock->statsMem);
+
+ if (LIKELY(stats == NULL)) {
+ MXUserStats *before;
+
+ stats = Util_SafeCalloc(1, sizeof(*stats));
+
+ MXUserAcquisitionStatsSetUp(&stats->acquisitionStats);
+ MXUserBasicStatsSetUp(&stats->heldStats, MXUSER_STAT_CLASS_HELD);
+
+ before = (MXUserStats *) Atomic_ReadIfEqualWritePtr(&lock->statsMem,
+ NULL,
+ (void *) stats);
+
+ if (before) {
+ free(stats);
+ }
+
+ lock->header.statsFunc = MXUserStatsActionExcl;
+ }
+
+ result = TRUE;
+ break;
+ }
+
default:
result = FALSE;
}
lock->header.dumpFunc = MXUserDumpExclLock;
if (MXUserStatsEnabled()) {
- MXUserStats *stats = Util_SafeCalloc(1, sizeof(*stats));
-
- MXUserAcquisitionStatsSetUp(&stats->acquisitionStats);
- MXUserBasicStatsSetUp(&stats->heldStats, MXUSER_STAT_CLASS_HELD);
+ Bool success = MXUser_ControlExclLock(lock, MXUSER_CONTROL_ENABLE_STATS);
- lock->header.statsFunc = MXUserStatsActionExcl;
- Atomic_WritePtr(&lock->statsMem, stats);
+ ASSERT(success);
} else {
lock->header.statsFunc = NULL;
Atomic_WritePtr(&lock->statsMem, NULL);
}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MXUser_ControlRWLock --
+ *
+ * Perform the specified command on the specified lock.
+ *
+ * Results:
+ * TRUE succeeded
+ * FALSE failed
+ *
+ * Side effects:
+ * Depends on the command, no?
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+MXUser_ControlRWLock(MXUserRWLock *lock, // IN/OUT:
+ uint32 command, // IN:
+ ...) // IN:
+{
+ Bool result;
+
+ ASSERT(lock && (lock->header.signature == MXUSER_RW_SIGNATURE));
+
+ switch (command) {
+ case MXUSER_CONTROL_ACQUISITION_HISTO: {
+ MXUserStats *stats = (MXUserStats *) Atomic_ReadPtr(&lock->statsMem);
+
+ if (stats) {
+ va_list a;
+ uint64 minValue;
+ uint32 decades;
+
+ 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: {
+ MXUserStats *stats = (MXUserStats *) Atomic_ReadPtr(&lock->statsMem);
+
+ if (stats) {
+ va_list a;
+ uint32 minValue;
+ uint32 decades;
+
+ 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: {
+ MXUserStats *stats = (MXUserStats *) Atomic_ReadPtr(&lock->statsMem);
+
+ if (LIKELY(stats == NULL)) {
+ MXUserStats *before;
+
+ stats = Util_SafeCalloc(1, sizeof(*stats));
+
+ MXUserAcquisitionStatsSetUp(&stats->acquisitionStats);
+ MXUserBasicStatsSetUp(&stats->heldStats, MXUSER_STAT_CLASS_HELD);
+
+ before = (MXUserStats *) Atomic_ReadIfEqualWritePtr(&lock->statsMem,
+ NULL,
+ (void *) stats);
+
+ if (before) {
+ free(stats);
+ }
+
+ lock->header.statsFunc = MXUserStatsActionRW;
+ }
+
+ result = TRUE;
+ break;
+ }
+
+ default:
+ result = FALSE;
+ }
+
+ return result;
+}
+
+
/*
*-----------------------------------------------------------------------------
*
MXUserFreeHashEntry);
if (MXUserStatsEnabled()) {
- MXUserStats *stats = Util_SafeCalloc(1, sizeof(*stats));
+ Bool success = MXUser_ControlRWLock(lock,
+ MXUSER_CONTROL_ENABLE_STATS);
- MXUserAcquisitionStatsSetUp(&stats->acquisitionStats);
- MXUserBasicStatsSetUp(&stats->heldStats, MXUSER_STAT_CLASS_HELD);
-
- lock->header.statsFunc = MXUserStatsActionRW;
- Atomic_WritePtr(&lock->statsMem, stats);
+ ASSERT(success);
} else {
lock->header.statsFunc = NULL;
Atomic_WritePtr(&lock->statsMem, NULL);
break;
}
+ case MXUSER_CONTROL_ENABLE_STATS: {
+ MXUserStats *stats = (MXUserStats *) Atomic_ReadPtr(&lock->statsMem);
+
+ if (LIKELY(stats == NULL)) {
+ MXUserStats *before;
+
+ stats = Util_SafeCalloc(1, sizeof(*stats));
+
+ MXUserAcquisitionStatsSetUp(&stats->acquisitionStats);
+ MXUserBasicStatsSetUp(&stats->heldStats, MXUSER_STAT_CLASS_HELD);
+
+ before = (MXUserStats *) Atomic_ReadIfEqualWritePtr(&lock->statsMem,
+ NULL,
+ (void *) stats);
+
+ if (before) {
+ free(stats);
+ }
+
+ lock->header.statsFunc = MXUserStatsActionRec;
+ }
+
+ result = TRUE;
+ break;
+ }
+
default:
result = FALSE;
}
lock->header.statsFunc = NULL;
Atomic_WritePtr(&lock->statsMem, NULL);
} else {
- MXUserStats *stats = Util_SafeCalloc(1, sizeof(*stats));
-
- MXUserAcquisitionStatsSetUp(&stats->acquisitionStats);
- MXUserBasicStatsSetUp(&stats->heldStats, MXUSER_STAT_CLASS_HELD);
+ Bool success = MXUser_ControlRecLock(lock, MXUSER_CONTROL_ENABLE_STATS);
- lock->header.statsFunc = MXUserStatsActionRec;
- Atomic_WritePtr(&lock->statsMem, stats);
+ ASSERT(success);
}
MXUserAddToList(&lock->header);