From: VMware, Inc <> Date: Thu, 18 Nov 2010 21:27:25 +0000 (-0800) Subject: lib/lock: provide full control of statistics X-Git-Tag: 2010.11.17-327185~71 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2bb9eff4a9a277be823eb6c14f6031e89e1c6b00;p=thirdparty%2Fopen-vm-tools.git lib/lock: provide full control of statistics 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 --- diff --git a/open-vm-tools/lib/include/userlock.h b/open-vm-tools/lib/include/userlock.h index 6dba3e162..bddeaea76 100644 --- a/open-vm-tools/lib/include/userlock.h +++ b/open-vm-tools/lib/include/userlock.h @@ -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 diff --git a/open-vm-tools/lib/lock/ulExcl.c b/open-vm-tools/lib/lock/ulExcl.c index 1656a88cd..15c349614 100644 --- a/open-vm-tools/lib/lock/ulExcl.c +++ b/open-vm-tools/lib/lock/ulExcl.c @@ -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); diff --git a/open-vm-tools/lib/lock/ulRW.c b/open-vm-tools/lib/lock/ulRW.c index fff666b02..2dd86a2e9 100644 --- a/open-vm-tools/lib/lock/ulRW.c +++ b/open-vm-tools/lib/lock/ulRW.c @@ -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); diff --git a/open-vm-tools/lib/lock/ulRec.c b/open-vm-tools/lib/lock/ulRec.c index 2eb39716c..f0e253202 100644 --- a/open-vm-tools/lib/lock/ulRec.c +++ b/open-vm-tools/lib/lock/ulRec.c @@ -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);