MXUserRecLock * MXUser_BindMXMutexRec(struct MX_MutexRec *mutex, // IN: MX_Rank rank) // IN: { char *name; 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) || (MXUserMX_NameRec == 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 * system will take care of this. */ lock = Util_SafeCalloc(1, sizeof *lock); lock->header.signature = MXUserGetSignature(MXUSER_TYPE_REC); name = (*MXUserMX_NameRec)(mutex); if (name == NULL) { lock->header.name = Str_SafeAsprintf(NULL, "MX_%p", mutex); } else { lock->header.name = Str_SafeAsprintf(NULL, "%s *", name); } lock->header.rank = rank; lock->header.bits.serialNumber = MXUserAllocSerialNumber(); lock->header.dumpFunc = NULL; lock->header.statsFunc = NULL; Atomic_WritePtr(&lock->acquireStatsMem, NULL); Atomic_WritePtr(&lock->heldStatsMem, NULL); Atomic_Write(&lock->refCount, 1); lock->vmmLock = mutex; return lock; }
MXUserSemaphore * MXUser_CreateSemaphore(const char *userName, // IN: MX_Rank rank) // IN: { char *properName; MXUserSemaphore *sema; sema = Util_SafeCalloc(1, sizeof(*sema)); if (userName == NULL) { properName = Str_SafeAsprintf(NULL, "Sema-%p", GetReturnAddress()); } else { properName = Util_SafeStrdup(userName); } if (LIKELY(MXUserInit(&sema->nativeSemaphore) == 0)) { sema->header.signature = MXUserGetSignature(MXUSER_TYPE_SEMA); sema->header.name = properName; sema->header.rank = rank; sema->header.serialNumber = MXUserAllocSerialNumber(); sema->header.dumpFunc = MXUserDumpSemaphore; if (MXUserStatsMode() == 0) { sema->header.statsFunc = NULL; Atomic_WritePtr(&sema->acquireStatsMem, NULL); } else { MXUserAcquireStats *acquireStats; acquireStats = Util_SafeCalloc(1, sizeof(*acquireStats)); MXUserAcquisitionStatsSetUp(&acquireStats->data); sema->header.statsFunc = MXUserStatsActionSema; Atomic_WritePtr(&sema->acquireStatsMem, acquireStats); } MXUserAddToList(&sema->header); } else { free(properName); free(sema); sema = NULL; } return sema; }
MXUserExclLock * MXUser_CreateExclLock(const char *userName, // IN: MX_Rank rank) // IN: { Bool doStats; char *properName; MXUserExclLock *lock; lock = Util_SafeCalloc(1, sizeof(*lock)); if (userName == NULL) { properName = Str_SafeAsprintf(NULL, "X-%p", GetReturnAddress()); } else { properName = Util_SafeStrdup(userName); } if (!MXRecLockInit(&lock->recursiveLock)) { free(properName); free(lock); return NULL; } lock->header.signature = MXUserGetSignature(MXUSER_TYPE_EXCL); lock->header.name = properName; lock->header.rank = rank; lock->header.serialNumber = MXUserAllocSerialNumber(); lock->header.dumpFunc = MXUserDumpExclLock; if (vmx86_stats) { doStats = MXUserStatsEnabled(); } else { doStats = FALSE; } if (doStats) { MXUser_ControlExclLock(lock, MXUSER_CONTROL_ENABLE_STATS); } else { lock->header.statsFunc = NULL; Atomic_WritePtr(&lock->statsMem, NULL); } MXUserAddToList(&lock->header); return lock; }
MXUserRWLock * MXUser_CreateRWLock(const char *userName, // IN: MX_Rank rank) // IN: { Bool lockInited; char *properName; MXUserRWLock *lock; Bool useNative = MXUserNativeRWSupported(); lock = Util_SafeCalloc(1, sizeof(*lock)); if (userName == NULL) { if (LIKELY(useNative)) { properName = Str_SafeAsprintf(NULL, "RW-%p", GetReturnAddress()); } else { /* emulated */ properName = Str_SafeAsprintf(NULL, "RWemul-%p", GetReturnAddress()); } } else { properName = Util_SafeStrdup(userName); } lock->header.signature = MXUserGetSignature(MXUSER_TYPE_RW); lock->header.name = properName; lock->header.rank = rank; lock->header.serialNumber = MXUserAllocSerialNumber(); lock->header.dumpFunc = MXUserDumpRWLock; /* * Always attempt to use native locks when they are available. If, for some * reason, a native lock should be available but isn't, fall back to using * an internal recursive lock - something is better than nothing. */ lock->useNative = useNative && MXUserNativeRWInit(&lock->nativeLock); lockInited = MXRecLockInit(&lock->recursiveLock); if (LIKELY(lockInited)) { Bool doStats; lock->holderTable = HashTable_Alloc(256, HASH_INT_KEY | HASH_FLAG_ATOMIC, MXUserFreeHashEntry); if (vmx86_stats) { doStats = MXUserStatsEnabled(); } else { doStats = FALSE; } if (doStats) { MXUser_ControlRWLock(lock, MXUSER_CONTROL_ENABLE_STATS); } else { lock->header.statsFunc = NULL; Atomic_WritePtr(&lock->statsMem, NULL); } MXUserAddToList(&lock->header); } else { if (lock->useNative) { MXUserNativeRWDestroy(&lock->nativeLock); } free(properName); free(lock); lock = NULL; } return lock; }