]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
lib/lock: press for a harder MX/MXUser separation
authorVMware, Inc <>
Thu, 17 Jun 2010 21:11:54 +0000 (14:11 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Thu, 17 Jun 2010 21:11:54 +0000 (14:11 -0700)
Since there is a function for MX to register hook functions with
MXUser, enhance it to provide additional function that allow
removing even more MX references throughout MXUser.

This change makes it possible to expose the bind MX to MXUser
functionality to userland - we can use that functionality outside
the VMX now.

The mutex.h and userlock.h include files are tweaked so that things
work properly if either of them comes first and the userlock.h file
is able to stand on its own inside and outside the VMX.

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

index 5b8a1edb86a483747d4741f878585dca4c1d17f8..20e9acb87ec18e2d9d28b6c6852b76db5618f703 100644 (file)
@@ -131,23 +131,20 @@ void MXUser_DestroyCondVar(MXUserCondVar *condVar);
 #define MXUSER_DEFAULT_HISTO_MIN_VALUE_NS  1000  // 1 usec
 #define MXUSER_DEFAULT_HISTO_DECADES       7     // 1 usec to 10 seconds
 
-#if defined(VMX86_VMX)
-#include "mutex.h"
-
-MXUserRecLock *MXUser_BindMXMutexRec(MX_MutexRec *mutex);
-MX_MutexRec   *MXUser_GetRecLockVmm(const MXUserRecLock *lock);
-MX_Rank        MXUser_GetRecLockRank(const MXUserRecLock *lock);
+struct MX_MutexRec;
 
-MXUserRecLock *MXUser_InitFromMXRec(const char *name, MX_MutexRec *mutex,
-                                    MX_Rank rank, Bool isBelowBull);
+#if defined(VMX86_VMX)
+MXUserRecLock *MXUser_InitFromMXRec(const char *name,
+                                    struct MX_MutexRec *mutex,
+                                    MX_Rank rank,
+                                    Bool isBelowBull);
 
 #if defined(__i386__) || defined(__x86_64__)
-#if defined(VMX86_STATS)
+#if defined(VMX86_STATS) 
 #define MXUSER_STATS  // stats "only inside the VMX" when requested
 #endif
 #endif  // X86 and X86-64
-
-#endif  // VMX86_VMX
+#endif
 
 #if defined(VMX86_DEBUG)
 #define MXUSER_DEBUG  // debugging "everywhere" when requested
@@ -164,7 +161,10 @@ void MXUser_StatisticsControl(double contentionRatio,
 void MXUser_LogStats(unsigned epoch);
 #endif
 
-extern void MXUser_SetInPanic(void);
-extern Bool MXUser_InPanic(void);
+void MXUser_SetInPanic(void);
+Bool MXUser_InPanic(void);
 
+MXUserRecLock       *MXUser_BindMXMutexRec(struct MX_MutexRec *mutex);
+struct MX_MutexRec  *MXUser_GetRecLockVmm(const MXUserRecLock *lock);
+MX_Rank              MXUser_GetRecLockRank(const MXUserRecLock *lock);
 #endif  // _USERLOCK_H_
index eb8606b9890f3e6f0ddd010b20ddc09344d4af00..30c322069515bf378c62403e8aa0f14e50e8eee6 100644 (file)
@@ -21,6 +21,7 @@
 #include "util.h"
 #include "userlock.h"
 #include "ulInt.h"
+#include "ulIntShared.h"
 #include "hashTable.h"
 
 
@@ -30,6 +31,10 @@ Bool (*MXUserTryAcquireForceFail)() = NULL;
 
 static MX_Rank (*MXUserMxCheckRank)(void) = NULL;
 static void (*MXUserMxLockLister)(void) = NULL;
+void (*MXUserMX_LockRec)(struct MX_MutexRec *lock) = NULL;
+void (*MXUserMX_UnlockRec)(struct MX_MutexRec *lock) = NULL;
+Bool (*MXUserMX_TryLockRec)(struct MX_MutexRec *lock) = NULL;
+Bool (*MXUserMX_IsLockedByCurThreadRec)(const struct MX_MutexRec *lock) = NULL;
 
 
 #if defined(MXUSER_DEBUG) || defined(MXUSER_STATS)
@@ -561,8 +566,12 @@ MXUser_InPanic(void)
  */
 
 void
-MXUserInstallMxHooks(void (*theMxLockLister)(void),   // IN: MX list function
-                     MX_Rank (*theMxRankFunc)(void))  // IN: MX rank function
+MXUserInstallMxHooks(void (*theLockListFunc)(void),
+                     MX_Rank (*theRankFunc)(void),
+                     void (*theLockFunc)(struct MX_MutexRec *lock),
+                     void (*theUnlockFunc)(struct MX_MutexRec *lock),
+                     Bool (*theTryLockFunc)(struct MX_MutexRec *lock),
+                     Bool (*theIsLockedFunc)(const struct MX_MutexRec *lock))
 {
    /*
     * This function can be called more than once but the second and later
@@ -571,12 +580,24 @@ MXUserInstallMxHooks(void (*theMxLockLister)(void),   // IN: MX list function
     */
 
    if ((MXUserMxLockLister == NULL) &&
-       (MXUserMxCheckRank == NULL)) {
-      MXUserMxLockLister = theMxLockLister;
-      MXUserMxCheckRank = theMxRankFunc;
+       (MXUserMxCheckRank == NULL) &&
+       (MXUserMX_LockRec == NULL) &&
+       (MXUserMX_UnlockRec == NULL) &&
+       (MXUserMX_TryLockRec == NULL) &&
+       (MXUserMX_IsLockedByCurThreadRec == NULL)) {
+      MXUserMxLockLister = theLockListFunc;
+      MXUserMxCheckRank = theRankFunc;
+      MXUserMX_LockRec = theLockFunc;
+      MXUserMX_UnlockRec = theUnlockFunc;
+      MXUserMX_TryLockRec = theTryLockFunc;
+      MXUserMX_IsLockedByCurThreadRec = theIsLockedFunc;
    } else {
-      ASSERT((MXUserMxLockLister == theMxLockLister) &&
-             (MXUserMxCheckRank == theMxRankFunc)
+      ASSERT((MXUserMxLockLister == theLockListFunc) &&
+             (MXUserMxCheckRank == theRankFunc) &&
+             (MXUserMX_LockRec == theLockFunc) &&
+             (MXUserMX_UnlockRec == theUnlockFunc) &&
+             (MXUserMX_TryLockRec == theTryLockFunc) &&
+             (MXUserMX_IsLockedByCurThreadRec == theIsLockedFunc)
             );
    }
 }
index bfc4c7863c5919e416398a5588fab8686aafd86a..e0df7d4e803c6f19223d3f5bf6734c608eb66cab 100644 (file)
@@ -38,7 +38,6 @@ typedef pthread_t MXThreadID;
 
 #include "vm_basic_types.h"
 #include "vthreadBase.h"
-#include "ulIntShared.h"
 
 #if defined(MXUSER_STATS)
 #include "circList.h"
@@ -556,4 +555,9 @@ void MXUserForceHisto(Atomic_Ptr *histoPtr,
                       uint32 decades);
 #endif
 
+extern void (*MXUserMX_LockRec)(struct MX_MutexRec *lock);
+extern void (*MXUserMX_UnlockRec)(struct MX_MutexRec *lock);
+extern Bool (*MXUserMX_TryLockRec)(struct MX_MutexRec *lock);
+extern Bool (*MXUserMX_IsLockedByCurThreadRec)(const struct MX_MutexRec *lock);
+
 #endif
index 3303323884ed21105173e907b08bf1abc1026468..9e2d439c41757fe281423d5a6113530543c269b8 100644 (file)
 extern void MXUserListLocks(void);
 
 extern void MXUserInstallMxHooks(void (*theLockListFunc)(void),
-                                 MX_Rank (*theRankFunc)(void));
+                                 MX_Rank (*theRankFunc)(void),
+                                 void (*theLockFunc)(struct MX_MutexRec *lock),
+                                 void (*theUnlockFunc)(struct MX_MutexRec *lock),
+                                 Bool (*theTryLockFunc)(struct MX_MutexRec *lock),
+                                 Bool (*theIsLockedFunc)(const struct MX_MutexRec *lock));
 
 #endif
index 99ad0d2438e6f4582cb6fb2135774f6afac4e3b8..f19075ea2e4fb690f6a289ec66920f5e79653c23 100644 (file)
 #include "userlock.h"
 #include "ulInt.h"
 
-#if defined(VMX86_VMX)
-#include "mutexInt.h"
-#include "mutexRank.h"
-#else
-typedef struct MX_MutexRec MX_MutexRec;
-
-static INLINE void
-MX_LockRec(MX_MutexRec *lock)  // IN:
-{
-   NOT_IMPLEMENTED();
-}
-
-static INLINE void
-MX_UnlockRec(MX_MutexRec *lock)  // IN:
-{
-   NOT_IMPLEMENTED();
-}
-
-static INLINE Bool 
-MX_TryLockRec(MX_MutexRec *lock)  // IN:
-{
-   NOT_IMPLEMENTED();
-}
-
-static INLINE Bool 
-MX_IsLockedByCurThreadRec(MX_MutexRec *lock)  // IN:
-{
-   NOT_IMPLEMENTED();
-}
-#endif
-
 struct MXUserRecLock
 {
    MXUserHeader            header;
@@ -79,7 +48,7 @@ struct MXUserRecLock
     *         MXUser_BindMXMutexRec was used to create the lock
     */
 
-   MX_MutexRec            *vmmLock;
+   struct MX_MutexRec     *vmmLock;
 };
 
 #if defined(MXUSER_STATS)
@@ -279,7 +248,7 @@ MXUser_DestroyRecLock(MXUserRecLock *lock)  // IN:
    if (lock != NULL) {
       ASSERT(lock->header.lockSignature == USERLOCK_SIGNATURE);
 
-      if (!lock->vmmLock) {
+      if (lock->vmmLock == NULL) {
          if (MXRecLockCount(&lock->recursiveLock) > 0) {
             MXUserDumpAndPanic(&lock->header,
                                "%s: Destroy of an acquired recursive lock\n",
@@ -327,7 +296,8 @@ MXUser_AcquireRecLock(MXUserRecLock *lock)  // IN/OUT:
    ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE));
 
    if (lock->vmmLock) {
-      MX_LockRec(lock->vmmLock);
+      ASSERT(MXUserMX_LockRec);
+      (*MXUserMX_LockRec)(lock->vmmLock);
    } else {
 #if defined(MXUSER_STATS)
       Bool contended;
@@ -386,7 +356,8 @@ MXUser_ReleaseRecLock(MXUserRecLock *lock)  // IN/OUT:
    ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE));
 
    if (lock->vmmLock) {
-      MX_UnlockRec(lock->vmmLock);
+      ASSERT(MXUserMX_UnlockRec);
+      (*MXUserMX_UnlockRec)(lock->vmmLock);
    } else {
 #if defined(MXUSER_STATS)
       if (MXRecLockCount(&lock->recursiveLock) == 1) {
@@ -448,7 +419,8 @@ MXUser_TryAcquireRecLock(MXUserRecLock *lock)  // IN/OUT:
    ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE));
 
    if (lock->vmmLock) {
-      success = MX_TryLockRec(lock->vmmLock);
+      ASSERT(MXUserMX_TryLockRec);
+      success = (*MXUserMX_TryLockRec)(lock->vmmLock);
    } else {
 #if defined(MXUSER_STATS)
       uint64 begin;
@@ -500,10 +472,17 @@ MXUser_TryAcquireRecLock(MXUserRecLock *lock)  // IN/OUT:
 Bool
 MXUser_IsCurThreadHoldingRecLock(const MXUserRecLock *lock)  // IN:
 {
+   Bool result;
    ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE));
 
-   return (lock->vmmLock) ? MX_IsLockedByCurThreadRec(lock->vmmLock) :
-                            MXRecLockIsOwner(&lock->recursiveLock);
+   if (lock->vmmLock) {
+      ASSERT(MXUserMX_IsLockedByCurThreadRec);
+      result = (*MXUserMX_IsLockedByCurThreadRec)(lock->vmmLock);
+   } else {
+      result = MXRecLockIsOwner(&lock->recursiveLock);
+   }
+
+   return result;
 }
 
 
@@ -532,6 +511,7 @@ MXUser_ControlRecLock(MXUserRecLock *lock,  // IN/OUT:
    Bool result;
 
    ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE));
+   ASSERT(lock->vmmLock == NULL);  // only unbound locks
 
    switch (command) {
 #if defined(MXUSER_STATS)
@@ -646,6 +626,7 @@ MXUserCondVar *
 MXUser_CreateCondVarRecLock(MXUserRecLock *lock)
 {
    ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE));
+   ASSERT(lock->vmmLock == NULL);  // only unbound locks
 
    return MXUserCreateCondVar(&lock->header, &lock->recursiveLock);
 }
@@ -674,12 +655,12 @@ MXUser_WaitCondVarRecLock(MXUserRecLock *lock,     // IN:
                           MXUserCondVar *condVar)  // IN:
 {
    ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE));
+   ASSERT(lock->vmmLock == NULL);  // only unbound locks
 
    MXUserWaitCondVar(&lock->header, &lock->recursiveLock, condVar);
 }
 
 
-#if defined(VMX86_VMX)
 /*
  *-----------------------------------------------------------------------------
  *
@@ -696,7 +677,7 @@ MXUser_WaitCondVarRecLock(MXUserRecLock *lock,     // IN:
  *-----------------------------------------------------------------------------
  */
 
-MX_MutexRec *
+struct MX_MutexRec *
 MXUser_GetRecLockVmm(const MXUserRecLock *lock)  // IN:
 {
    ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE));
@@ -749,12 +730,24 @@ MXUser_GetRecLockRank(const MXUserRecLock *lock)  // IN:
  */
 
 MXUserRecLock *
-MXUser_BindMXMutexRec(MX_MutexRec *mutex)  // IN:
+MXUser_BindMXMutexRec(struct MX_MutexRec *mutex)  // IN:
 {
    MXUserRecLock *lock;
 
    ASSERT(mutex);
 
+   /*
+    * Cannot perform a binding unless MX_Init has been called. As a side
+    * effect it registers these hook functions.
+    */
+
+   if ((MXUserMX_LockRec == NULL) ||
+       (MXUserMX_UnlockRec == NULL) ||
+       (MXUserMX_TryLockRec == NULL) ||
+       (MXUserMX_IsLockedByCurThreadRec == NULL)) {
+       return NULL;
+    }
+
    /*
     * Initialize the header (so it looks correct in memory) but don't connect
     * this lock to the MXUser statistics or debugging tracking - the MX lock
@@ -763,11 +756,10 @@ MXUser_BindMXMutexRec(MX_MutexRec *mutex)  // IN:
 
    lock = Util_SafeCalloc(1, sizeof(*lock));
 
-   lock->header.lockName = Str_SafeAsprintf(NULL, "MX_LockID%d",
-                                            mutex->lck.lid);
+   lock->header.lockName = Str_SafeAsprintf(NULL, "MX_%p", mutex);
 
    lock->header.lockSignature = USERLOCK_SIGNATURE;
-   lock->header.lockRank = mutex->lck.rank;
+   lock->header.lockRank = RANK_UNRANKED;  // unused
    lock->header.lockDumper = NULL;
 
 #if defined(MXUSER_STATS)
@@ -781,6 +773,9 @@ MXUser_BindMXMutexRec(MX_MutexRec *mutex)  // IN:
 }
 
 
+#if defined(VMX86_VMX)
+#include "mutex.h"
+
 /*
  *----------------------------------------------------------------------------
  *