From: VMware, Inc <> Date: Mon, 21 Nov 2011 22:46:17 +0000 (-0800) Subject: lib/lock: no bag on the side reference counting X-Git-Tag: 2011.11.20-535097~91 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8bb1fc798a2454136daed8f1b4d4a020da0a3f1e;p=thirdparty%2Fopen-vm-tools.git lib/lock: no bag on the side reference counting 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 --- diff --git a/open-vm-tools/lib/include/userlock.h b/open-vm-tools/lib/include/userlock.h index 8e798db9b..6c98bc814 100644 --- a/open-vm-tools/lib/include/userlock.h +++ b/open-vm-tools/lib/include/userlock.h @@ -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 */ diff --git a/open-vm-tools/lib/lock/ulExcl.c b/open-vm-tools/lib/lock/ulExcl.c index 2141a2cf1..5bb44e740 100644 --- a/open-vm-tools/lib/lock/ulExcl.c +++ b/open-vm-tools/lib/lock/ulExcl.c @@ -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)); diff --git a/open-vm-tools/lib/lock/ulRec.c b/open-vm-tools/lib/lock/ulRec.c index 3f4fe5611..3f8b06c6f 100644 --- a/open-vm-tools/lib/lock/ulRec.c +++ b/open-vm-tools/lib/lock/ulRec.c @@ -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"