]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
lib/lock: provide full control of statistics
authorVMware, Inc <>
Thu, 18 Nov 2010 21:27:25 +0000 (13:27 -0800)
committerMarcelo Vanzin <mvanzin@vmware.com>
Thu, 18 Nov 2010 21:27:25 +0000 (13:27 -0800)
Allow the MXUser_Control functions to fully enable statistics on
exclusive, recursive and RW locks. This allows a developer to
enable statistics on a lock by lock basis should a study warrant it.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/lib/include/userlock.h
open-vm-tools/lib/lock/ulExcl.c
open-vm-tools/lib/lock/ulRW.c
open-vm-tools/lib/lock/ulRec.c

index 6dba3e1629c7c3ced516164ffc1de0bd406a9258..bddeaea76b0e58034e43b4d859dad1f66ef0bfa7 100644 (file)
@@ -129,6 +129,10 @@ MXUserRWLock *MXUser_CreateSingletonRWLock(Atomic_Ptr *lockStorage,
                                            const char *name,
                                            MX_Rank rank);
 
+Bool MXUser_ControlRWLock(MXUserRWLock *lock,
+                          uint32 command,
+                          ...);
+
 /*
  * Computational barrier
  */
@@ -190,11 +194,12 @@ void MXUser_BroadcastCondVar(MXUserCondVar *condVar);
 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
index 1656a88cd168e61fcdc0f9c800d7b5ae95bb1ded..15c34961412397ac0c40ab67696fe36fe0f78e77 100644 (file)
@@ -225,6 +225,32 @@ MXUser_ControlExclLock(MXUserExclLock *lock,  // IN/OUT:
       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;
    }
@@ -279,13 +305,9 @@ MXUser_CreateExclLock(const char *userName,  // IN:
    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);
index fff666b020977932d02b7ae57ba08b825360a8eb..2dd86a2e97a8c33086c95831bd0cb6b0c758eda5 100644 (file)
@@ -378,6 +378,115 @@ MXUserDumpRWLock(MXUserHeader *header)  // IN:
 }
 
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * 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;
+}
+
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -442,13 +551,10 @@ MXUser_CreateRWLock(const char *userName,  // IN:
                                           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);
index 2eb39716c8042068524c006a744a9b6942be753b..f0e253202438a21000158b27b8f5d958cf8cf7a7 100644 (file)
@@ -247,6 +247,32 @@ MXUser_ControlRecLock(MXUserRecLock *lock,  // IN/OUT:
       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;
    }
@@ -310,13 +336,9 @@ MXUserCreateRecLock(const char *userName,  // IN:
       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);