#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
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_
#include "util.h"
#include "userlock.h"
#include "ulInt.h"
+#include "ulIntShared.h"
#include "hashTable.h"
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)
*/
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
*/
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)
);
}
}
#include "vm_basic_types.h"
#include "vthreadBase.h"
-#include "ulIntShared.h"
#if defined(MXUSER_STATS)
#include "circList.h"
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
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
#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;
* MXUser_BindMXMutexRec was used to create the lock
*/
- MX_MutexRec *vmmLock;
+ struct MX_MutexRec *vmmLock;
};
#if defined(MXUSER_STATS)
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",
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;
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) {
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;
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;
}
Bool result;
ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE));
+ ASSERT(lock->vmmLock == NULL); // only unbound locks
switch (command) {
#if defined(MXUSER_STATS)
MXUser_CreateCondVarRecLock(MXUserRecLock *lock)
{
ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE));
+ ASSERT(lock->vmmLock == NULL); // only unbound locks
return MXUserCreateCondVar(&lock->header, &lock->recursiveLock);
}
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)
/*
*-----------------------------------------------------------------------------
*
*-----------------------------------------------------------------------------
*/
-MX_MutexRec *
+struct MX_MutexRec *
MXUser_GetRecLockVmm(const MXUserRecLock *lock) // IN:
{
ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE));
*/
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
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)
}
+#if defined(VMX86_VMX)
+#include "mutex.h"
+
/*
*----------------------------------------------------------------------------
*