Atomic_Inc(&condVar->referenceCount);
+ /*
+ * When using the native lock found within the MXUser lock, be sure to
+ * decrement the count before the wait/sleep and increment it after the
+ * wait/sleep - the (native) wait/sleep will perform a lock release before
+ * the wait/sleep and a lock acquisition after the wait/sleep. The
+ * MXUser internal accounting information must be maintained.
+ */
+
#if defined(_WIN32)
if (pSleepConditionVariableCS) {
+ MXRecLockDecCount(lock);
err = (*pSleepConditionVariableCS)(&condVar->x.condObject,
&lock->nativeLock, INFINITE) ?
0 : GetLastError();
+ MXRecLockIncCount(lock, GetReturnAddress());
} else {
Bool done = FALSE;
err = 0;
}
#else
+ MXRecLockDecCount(lock);
err = pthread_cond_wait(&condVar->condObject, &lock->nativeLock);
+ MXRecLockIncCount(lock, GetReturnAddress());
#endif
if (err != 0) {
if (vmx86_debug && (err != 0)) {
Panic("%s: MXRecLockDestroyInternal returned %d\n", __FUNCTION__, err);
}
+}
+
+
+static INLINE uint32
+MXRecLockCount(const MXRecLock *lock) // IN:
+{
+ return lock->referenceCount;
+}
+
+
+static INLINE void
+MXRecLockIncCount(MXRecLock *lock, // IN/OUT:
+ void *location) // IN:
+{
+ if (MXRecLockCount(lock) == 0) {
+#if defined(MXUSER_DEBUG)
+ ASSERT(lock->portableThreadID == VTHREAD_INVALID_ID);
+
+ lock->ownerRetAddr = location;
+ lock->portableThreadID = VThread_CurID();
+#endif
+
+ MXRecLockSetOwner(lock);
+ }
+
+ lock->referenceCount++;
}
{
Bool contended;
- if ((lock->referenceCount != 0) && MXRecLockIsOwner(lock)) {
- ASSERT((lock->referenceCount > 0) &&
- (lock->referenceCount < MXUSER_MAX_REC_DEPTH));
-
- lock->referenceCount++;
+ if ((MXRecLockCount(lock) != 0) && MXRecLockIsOwner(lock)) {
+ ASSERT((MXRecLockCount(lock) > 0) &&
+ (MXRecLockCount(lock) < MXUSER_MAX_REC_DEPTH));
contended = FALSE;
} else {
}
ASSERT(lock->referenceCount == 0);
-
-#if defined(MXUSER_DEBUG)
- ASSERT(lock->portableThreadID == VTHREAD_INVALID_ID);
-
- lock->ownerRetAddr = location;
- lock->portableThreadID = VThread_CurID();
-#endif
-
- MXRecLockSetOwner(lock);
- lock->referenceCount = 1;
}
+ MXRecLockIncCount(lock, location);
+
return contended;
}
err = MXRecLockTryAcquireInternal(lock);
if (err == 0) {
- ASSERT((lock->referenceCount >= 0) &&
- (lock->referenceCount < MXUSER_MAX_REC_DEPTH));
-
- if (lock->referenceCount == 0) {
-#if defined(MXUSER_DEBUG)
- ASSERT(lock->portableThreadID == VTHREAD_INVALID_ID);
-
- lock->ownerRetAddr = location;
- lock->portableThreadID = VThread_CurID();
-#endif
-
- MXRecLockSetOwner(lock);
- }
+ ASSERT((MXRecLockCount(lock) > 0) &&
+ (MXRecLockCount(lock) < MXUSER_MAX_REC_DEPTH));
- lock->referenceCount++;
+ MXRecLockIncCount(lock, location);
acquired = TRUE;
} else {
return acquired;
}
-
static INLINE void
-MXRecLockRelease(MXRecLock *lock) // IN/OUT:
+MXRecLockDecCount(MXRecLock *lock) // IN/OUT:
{
- ASSERT((lock->referenceCount > 0) &&
- (lock->referenceCount < MXUSER_MAX_REC_DEPTH));
-
lock->referenceCount--;
- if (lock->referenceCount == 0) {
- int err;
-
+ if (MXRecLockCount(lock) == 0) {
MXRecLockSetNoOwner(lock);
#if defined(MXUSER_DEBUG)
lock->ownerRetAddr = NULL;
lock->portableThreadID = VTHREAD_INVALID_ID;
#endif
+ }
+}
+
+
+static INLINE void
+MXRecLockRelease(MXRecLock *lock) // IN/OUT:
+{
+ ASSERT((MXRecLockCount(lock) > 0) &&
+ (MXRecLockCount(lock) < MXUSER_MAX_REC_DEPTH));
- err = MXRecLockReleaseInternal(lock);
+ MXRecLockDecCount(lock);
+
+ if (MXRecLockCount(lock) == 0) {
+ int err = MXRecLockReleaseInternal(lock);
if (vmx86_debug && (err != 0)) {
Panic("%s: MXRecLockReleaseInternal returned %d\n", __FUNCTION__,
}
-static INLINE uint32
-MXRecLockCount(const MXRecLock *lock) // IN:
-{
- return lock->referenceCount;
-}
-
/*
* MXUser lock header - all MXUser locks start with this
*/