]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
lib/lock: no bag on the side reference counting
authorVMware, Inc <>
Mon, 21 Nov 2011 22:46:17 +0000 (14:46 -0800)
committerMarcelo Vanzin <mvanzin@vmware.com>
Mon, 21 Nov 2011 22:46:17 +0000 (14:46 -0800)
Use true reference counting on MXUser recursive locks. The destroy
function remains to maintain compatibility with the existing code
base.

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/ulRec.c

index 8e798db9bd33569a3372836cd9a27a10311350cc..6c98bc814c09ae7e8ffb12d1379beca36e2c3a5a 100644 (file)
@@ -51,7 +51,7 @@ void MXUser_AcquireExclLock(MXUserExclLock *lock);
 Bool MXUser_TryAcquireExclLock(MXUserExclLock *lock);
 void MXUser_ReleaseExclLock(MXUserExclLock *lock);
 void MXUser_DestroyExclLock(MXUserExclLock *lock);
-Bool MXUser_IsCurThreadHoldingExclLock(const MXUserExclLock *lock);
+Bool MXUser_IsCurThreadHoldingExclLock(MXUserExclLock *lock);
 
 MXUserExclLock *MXUser_CreateSingletonExclLock(Atomic_Ptr *lockStorage,
                                                const char *name,
@@ -85,7 +85,7 @@ void MXUser_AcquireRecLock(MXUserRecLock *lock);
 Bool MXUser_TryAcquireRecLock(MXUserRecLock *lock);
 void MXUser_ReleaseRecLock(MXUserRecLock *lock);
 void MXUser_DestroyRecLock(MXUserRecLock *lock);
-Bool MXUser_IsCurThreadHoldingRecLock(const MXUserRecLock *lock);
+Bool MXUser_IsCurThreadHoldingRecLock(MXUserRecLock *lock);
 
 MXUserRecLock *MXUser_CreateSingletonRecLock(Atomic_Ptr *lockStorage,
                                              const char *name,
@@ -110,9 +110,6 @@ void MXUser_IncRefRecLock(MXUserRecLock *lock);
 
 void MXUser_DecRefRecLock(MXUserRecLock *lock);
 
-Bool MXUser_AcquireWeakRefRecLock(MXUserRecLock *lock);
-
-
 /*
  * Read-write lock
  */
index 2141a2cf1414b6b800feb2a1654e8d219d528ac1..5bb44e740d736f62c2323c5599b3df5efeb0bfa4 100644 (file)
@@ -569,7 +569,7 @@ MXUser_TryAcquireExclLock(MXUserExclLock *lock)  // IN/OUT:
  */
 
 Bool
-MXUser_IsCurThreadHoldingExclLock(const MXUserExclLock *lock)  // IN:
+MXUser_IsCurThreadHoldingExclLock(MXUserExclLock *lock)  // IN:
 {
    ASSERT(lock && (lock->header.signature == MXUSER_EXCL_SIGNATURE));
 
index 3f4fe5611a09dcb9b98eacad870df108ad26a872..3f8b06c6f8b1e2855fad7e05a348dbbf58b28657 100644 (file)
@@ -42,8 +42,7 @@ struct MXUserRecLock
    MXUserHeader         header;
    MXRecLock            recursiveLock;
    Atomic_Ptr           statsMem;
-   Atomic_uint32        destroyRefCount;
-   Atomic_uint32        destroyWasCalled;
+   Atomic_uint32        refCount;
 
    /*
     * This is the MX recursive lock override pointer. It is used within the
@@ -156,6 +155,7 @@ MXUserDumpRecLock(MXUserHeader *header)  // IN:
    Warning("\tname %s\n", lock->header.name);
    Warning("\trank 0x%X\n", lock->header.rank);
    Warning("\tserial number %u\n", lock->header.serialNumber);
+   Warning("\treference count %u\n", Atomic_Read(&lock->refCount));
 
    if (lock->vmmLock == NULL) {
       MXUserStats *stats = (MXUserStats *) Atomic_ReadPtr(&lock->statsMem);
@@ -204,14 +204,17 @@ MXUser_ControlRecLock(MXUserRecLock *lock,  // IN/OUT:
 
    ASSERT(lock && (lock->header.signature == MXUSER_REC_SIGNATURE));
 
+   Atomic_Inc(&lock->refCount);
+
    switch (command) {
    case MXUSER_CONTROL_ACQUISITION_HISTO: {
       MXUserStats *stats = (MXUserStats *) Atomic_ReadPtr(&lock->statsMem);
 
       if (stats && (lock->vmmLock == NULL)) {
          va_list a;
-         uint64 minValue;
          uint32 decades;
+         uint64 minValue;
+
          va_start(a, command);
          minValue = va_arg(a, uint64);
          decades = va_arg(a, uint32);
@@ -232,8 +235,9 @@ MXUser_ControlRecLock(MXUserRecLock *lock,  // IN/OUT:
 
       if (stats && (lock->vmmLock == NULL)) {
          va_list a;
-         uint64 minValue;
          uint32 decades;
+         uint64 minValue;
+
          va_start(a, command);
          minValue = va_arg(a, uint64);
          decades = va_arg(a, uint32);
@@ -280,6 +284,10 @@ MXUser_ControlRecLock(MXUserRecLock *lock,  // IN/OUT:
       result = FALSE;
    }
 
+   if (Atomic_FetchAndDec(&lock->refCount) == 1) {
+      Panic("%s: Zero reference count upon exit\n", __FUNCTION__);
+   }
+
    return result;
 }
 
@@ -328,8 +336,7 @@ MXUserCreateRecLock(const char *userName,  // IN:
    }
 
    lock->vmmLock = NULL;
-   Atomic_Write(&lock->destroyRefCount, 1);
-   Atomic_Write(&lock->destroyWasCalled, 0);
+   Atomic_Write(&lock->refCount, 1);
 
    lock->header.signature = MXUSER_REC_SIGNATURE;
    lock->header.name = properName;
@@ -431,7 +438,7 @@ MXUserCondDestroyRecLock(MXUserRecLock *lock)  // IN:
 {
    ASSERT(lock && (lock->header.signature == MXUSER_REC_SIGNATURE));
 
-   if (Atomic_FetchAndDec(&lock->destroyRefCount) == 1) {
+   if (Atomic_FetchAndDec(&lock->refCount) == 1) {
       if (lock->vmmLock == NULL) {
          MXUserStats *stats;
 
@@ -468,21 +475,6 @@ void
 MXUser_DestroyRecLock(MXUserRecLock *lock)  // IN:
 {
    if (lock != NULL) {
-      ASSERT(lock->header.signature == MXUSER_REC_SIGNATURE);
-
-      /*
-       * May not call destroy on a lock more than once
-       *
-       * That the code can get here may only occur if the reference count
-       * mechanism is used.
-       */
-
-      if (Atomic_FetchAndInc(&lock->destroyWasCalled) != 0) {
-         MXUserDumpAndPanic(&lock->header,
-                            "%s: Destroy of a destroyed recursive lock\n",
-                            __FUNCTION__);
-      }
-
       MXUserCondDestroyRecLock(lock);
    }
 }
@@ -506,11 +498,13 @@ MXUser_DestroyRecLock(MXUserRecLock *lock)  // IN:
  *-----------------------------------------------------------------------------
  */
 
-static void
-MXUserAcquireRecLock(MXUserRecLock *lock)  // IN/OUT:
+void
+MXUser_AcquireRecLock(MXUserRecLock *lock)  // IN/OUT:
 {
    ASSERT(lock && (lock->header.signature == MXUSER_REC_SIGNATURE));
 
+   Atomic_Inc(&lock->refCount);
+
    if (lock->vmmLock) {
       ASSERT(MXUserMX_LockRec);
       (*MXUserMX_LockRec)(lock->vmmLock);
@@ -547,17 +541,10 @@ MXUserAcquireRecLock(MXUserRecLock *lock)  // IN/OUT:
          MXRecLockAcquire(&lock->recursiveLock);
       }
    }
-}
-
-
-void
-MXUser_AcquireRecLock(MXUserRecLock *lock)  // IN/OUT:
-{
-   ASSERT(lock && (lock->header.signature == MXUSER_REC_SIGNATURE));
-
-   ASSERT(Atomic_Read(&lock->destroyWasCalled) == 0);
 
-   MXUserAcquireRecLock(lock);
+   if (Atomic_FetchAndDec(&lock->refCount) == 1) {
+      Panic("%s: Zero reference count upon exit\n", __FUNCTION__);
+   }
 }
 
 
@@ -582,6 +569,8 @@ MXUser_ReleaseRecLock(MXUserRecLock *lock)  // IN/OUT:
 {
    ASSERT(lock && (lock->header.signature == MXUSER_REC_SIGNATURE));
 
+   Atomic_Inc(&lock->refCount);
+
    if (lock->vmmLock) {
       ASSERT(MXUserMX_UnlockRec);
       (*MXUserMX_UnlockRec)(lock->vmmLock);
@@ -615,6 +604,10 @@ MXUser_ReleaseRecLock(MXUserRecLock *lock)  // IN/OUT:
 
       MXRecLockRelease(&lock->recursiveLock);
    }
+
+   if (Atomic_FetchAndDec(&lock->refCount) == 1) {
+      Panic("%s: Zero reference count upon exit\n", __FUNCTION__);
+   }
 }
 
 
@@ -648,9 +641,7 @@ MXUser_TryAcquireRecLock(MXUserRecLock *lock)  // IN/OUT:
 
    ASSERT(lock && (lock->header.signature == MXUSER_REC_SIGNATURE));
 
-   if (UNLIKELY(Atomic_Read(&lock->destroyWasCalled) != 0)) {
-      return FALSE;
-   }
+   Atomic_Inc(&lock->refCount);
 
    if (lock->vmmLock) {
       ASSERT(MXUserMX_TryLockRec);
@@ -676,6 +667,10 @@ MXUser_TryAcquireRecLock(MXUserRecLock *lock)  // IN/OUT:
       }
    }
 
+   if (Atomic_FetchAndDec(&lock->refCount) == 1) {
+      Panic("%s: Zero reference count upon exit\n", __FUNCTION__);
+   }
+
    return success;
 }
 
@@ -698,11 +693,14 @@ MXUser_TryAcquireRecLock(MXUserRecLock *lock)  // IN/OUT:
  */
 
 Bool
-MXUser_IsCurThreadHoldingRecLock(const MXUserRecLock *lock)  // IN:
+MXUser_IsCurThreadHoldingRecLock(MXUserRecLock *lock)  // IN:
 {
    Bool result;
+
    ASSERT(lock && (lock->header.signature == MXUSER_REC_SIGNATURE));
 
+   Atomic_Inc(&lock->refCount);
+
    if (lock->vmmLock) {
       ASSERT(MXUserMX_IsLockedByCurThreadRec);
       result = (*MXUserMX_IsLockedByCurThreadRec)(lock->vmmLock);
@@ -710,6 +708,10 @@ MXUser_IsCurThreadHoldingRecLock(const MXUserRecLock *lock)  // IN:
       result = MXRecLockIsOwner(&lock->recursiveLock);
    }
 
+   if (Atomic_FetchAndDec(&lock->refCount) == 1) {
+      Panic("%s: Zero reference count upon exit\n", __FUNCTION__);
+   }
+
    return result;
 }
 
@@ -781,10 +783,20 @@ MXUser_CreateSingletonRecLock(Atomic_Ptr *lockStorage,  // IN/OUT:
 MXUserCondVar *
 MXUser_CreateCondVarRecLock(MXUserRecLock *lock)
 {
+   MXUserCondVar *condVar;
+
    ASSERT(lock && (lock->header.signature == MXUSER_REC_SIGNATURE));
    ASSERT(lock->vmmLock == NULL);  // only unbound locks
 
-   return MXUserCreateCondVar(&lock->header, &lock->recursiveLock);
+   Atomic_Inc(&lock->refCount);
+
+   condVar =  MXUserCreateCondVar(&lock->header, &lock->recursiveLock);
+
+   if (Atomic_FetchAndDec(&lock->refCount) == 1) {
+      Panic("%s: Zero reference count upon exit\n", __FUNCTION__);
+   }
+
+   return condVar;
 }
 
 
@@ -814,8 +826,14 @@ MXUser_WaitCondVarRecLock(MXUserRecLock *lock,     // IN:
    ASSERT(lock && (lock->header.signature == MXUSER_REC_SIGNATURE));
    ASSERT(lock->vmmLock == NULL);  // only unbound locks
 
+   Atomic_Inc(&lock->refCount);
+
    MXUserWaitCondVar(&lock->header, &lock->recursiveLock, condVar,
                      MXUSER_WAIT_INFINITE);
+
+   if (Atomic_FetchAndDec(&lock->refCount) == 1) {
+      Panic("%s: Zero reference count upon exit\n", __FUNCTION__);
+   }
 }
 
 
@@ -846,7 +864,13 @@ MXUser_TimedWaitCondVarRecLock(MXUserRecLock *lock,     // IN:
    ASSERT(lock && (lock->header.signature == MXUSER_REC_SIGNATURE));
    ASSERT(lock->vmmLock == NULL);  // only unbound locks
 
+   Atomic_Inc(&lock->refCount);
+
    MXUserWaitCondVar(&lock->header, &lock->recursiveLock, condVar, msecWait);
+
+   if (Atomic_FetchAndDec(&lock->refCount) == 1) {
+      Panic("%s: Zero reference count upon exit\n", __FUNCTION__);
+   }
 }
 
 
@@ -871,7 +895,13 @@ MXUser_DumpRecLock(MXUserRecLock *lock)  // IN:
 {
    ASSERT(lock && (lock->header.signature == MXUSER_REC_SIGNATURE));
 
+   Atomic_Inc(&lock->refCount);
+
    MXUserDumpRecLock(&lock->header);
+
+   if (Atomic_FetchAndDec(&lock->refCount) == 1) {
+      Panic("%s: Zero reference count upon exit\n", __FUNCTION__);
+   }
 }
 
 
@@ -979,8 +1009,7 @@ MXUser_BindMXMutexRec(struct MX_MutexRec *mutex,  // IN:
    lock->header.statsFunc = NULL;
 
    Atomic_WritePtr(&lock->statsMem, NULL);
-   Atomic_Write(&lock->destroyRefCount, 1);
-   Atomic_Write(&lock->destroyWasCalled, 0);
+   Atomic_Write(&lock->refCount, 1);
 
    lock->vmmLock = mutex;
 
@@ -1010,7 +1039,7 @@ MXUser_IncRefRecLock(MXUserRecLock *lock)  // IN:
 {
    ASSERT(lock && (lock->header.signature == MXUSER_REC_SIGNATURE));
 
-   Atomic_Inc(&lock->destroyRefCount);
+   Atomic_Inc(&lock->refCount);
 }
 
 
@@ -1040,39 +1069,6 @@ MXUser_DecRefRecLock(MXUserRecLock *lock)  // IN:
 }
 
 
-/*
- *-----------------------------------------------------------------------------
- *
- * MXUser_AcquireWeakRefRecLock --
- *
- *      Acquire a lock only if destroy has not be called on it. This is 
- *      special implementation that will have limited lifetime. Once Poll
- *      is upgraded to use trylock this implementation will go away.
- *
- * Results:
- *      As above
- *
- * Side effects:
- *      None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-MXUser_AcquireWeakRefRecLock(MXUserRecLock *lock)  // IN:
-{
-   ASSERT(lock && (lock->header.signature == MXUSER_REC_SIGNATURE));
-
-   if (Atomic_Read(&lock->destroyWasCalled) != 0) {
-      return FALSE;
-   } else {
-      MXUserAcquireRecLock(lock);
-
-      return TRUE;
-   }
-}
-
-
 #if defined(VMX86_VMX)
 #include "mutex.h"
 #include "mutexRankVMX.h"