void MXUserWaitCondVar(MXUserHeader *header, // IN: MXRecLock *lock, // IN: MXUserCondVar *condVar, // IN: uint32 msecWait) // IN: { ASSERT(header); ASSERT(lock); ASSERT(condVar); ASSERT(condVar->signature == MXUserGetSignature(MXUSER_TYPE_CONDVAR)); if (condVar->ownerLock != lock) { Panic("%s: invalid use of lock %s with condVar (0x%p; %s)\n", __FUNCTION__, header->name, condVar, condVar->header->name); } if (vmx86_debug && !MXRecLockIsOwner(lock)) { Panic("%s: lock %s for condVar (0x%p) not owned\n", __FUNCTION__, condVar->header->name, condVar); } Atomic_Inc(&condVar->referenceCount); MXUserWaitInternal(lock, condVar, msecWait); Atomic_Dec(&condVar->referenceCount); }
MXUserRecLock * MXUser_CreateRecLock(const char *userName, // IN: MX_Rank rank) // IN: { uint32 statsMode; char *properName; MXUserRecLock *lock = Util_SafeCalloc(1, sizeof *lock); if (userName == NULL) { properName = Str_SafeAsprintf(NULL, "R-%p", GetReturnAddress()); } else { properName = Util_SafeStrdup(userName); } if (!MXRecLockInit(&lock->recursiveLock)) { free(properName); free(lock); return NULL; } lock->vmmLock = NULL; Atomic_Write(&lock->refCount, 1); lock->header.signature = MXUserGetSignature(MXUSER_TYPE_REC); lock->header.name = properName; lock->header.rank = rank; lock->header.bits.serialNumber = MXUserAllocSerialNumber(); lock->header.dumpFunc = MXUserDumpRecLock; statsMode = MXUserStatsMode(); switch (statsMode) { case 0: MXUserDisableStats(&lock->acquireStatsMem, &lock->heldStatsMem); lock->header.statsFunc = NULL; break; case 1: MXUserEnableStats(&lock->acquireStatsMem, NULL); lock->header.statsFunc = MXUserStatsActionRec; break; case 2: MXUserEnableStats(&lock->acquireStatsMem, &lock->heldStatsMem); lock->header.statsFunc = MXUserStatsActionRec; break; default: Panic("%s: unknown stats mode: %d!\n", __FUNCTION__, statsMode); } MXUserAddToList(&lock->header); return lock; }
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; }
void MXUser_BroadcastCondVar(MXUserCondVar *condVar) // IN: { int err; ASSERT(condVar); ASSERT(condVar->signature == MXUserGetSignature(MXUSER_TYPE_CONDVAR)); err = MXUserBroadcastInternal(condVar); if (err != 0) { Panic("%s: failure %d on condVar (0x%p; %s) \n", __FUNCTION__, err, condVar, condVar->header->name); } }
MXUserCondVar * MXUserCreateCondVar(MXUserHeader *header, // IN: MXRecLock *lock) // IN: { MXUserCondVar *condVar = Util_SafeCalloc(1, sizeof *condVar); if (UNLIKELY(!MXUserCreateInternal(condVar))) { Panic("%s: native lock initialization routine failed\n", __FUNCTION__); } condVar->signature = MXUserGetSignature(MXUSER_TYPE_CONDVAR); condVar->header = header; condVar->ownerLock = lock; return condVar; }
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; }
MXUserCondVar * MXUserCreateCondVar(MXUserHeader *header, // IN: MXRecLock *lock) // IN: { MXUserCondVar *condVar = Util_SafeCalloc(1, sizeof(*condVar)); if (MXUserCreateInternal(condVar)) { condVar->signature = MXUserGetSignature(MXUSER_TYPE_CONDVAR); condVar->header = header; condVar->ownerLock = lock; } else { free(condVar); condVar = NULL; } return condVar; }
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; }
void MXUser_DestroyCondVar(MXUserCondVar *condVar) // IN: { if (condVar != NULL) { ASSERT(condVar->signature == MXUserGetSignature(MXUSER_TYPE_CONDVAR)); if (Atomic_Read(&condVar->referenceCount) != 0) { Panic("%s: Attempted destroy on active condVar (0x%p; %s)\n", __FUNCTION__, condVar, condVar->header->name); } condVar->signature = 0; // just in case... MXUserDestroyInternal(condVar); condVar->header = NULL; condVar->ownerLock = NULL; free(condVar); } }
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; }
MXUserRWLock * MXUser_CreateRWLock(const char *userName, // IN: MX_Rank rank) // IN: { Bool lockInited; char *properName; Bool useNative = MXUserNativeRWSupported(); MXUserRWLock *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.bits.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)) { uint32 statsMode; lock->holderTable = HashTable_Alloc(256, HASH_INT_KEY | HASH_FLAG_ATOMIC, MXUserFreeHashEntry); statsMode = MXUserStatsMode(); switch (MXUserStatsMode()) { case 0: MXUserDisableStats(&lock->acquireStatsMem, &lock->heldStatsMem); lock->header.statsFunc = NULL; break; case 1: MXUserEnableStats(&lock->acquireStatsMem, NULL); lock->header.statsFunc = MXUserStatsActionRW; break; case 2: MXUserEnableStats(&lock->acquireStatsMem, &lock->heldStatsMem); lock->header.statsFunc = MXUserStatsActionRW; break; default: Panic("%s: unknown stats mode: %d!\n", __FUNCTION__, statsMode); } MXUserAddToList(&lock->header); } else { Panic("%s: native lock initialization routine failed\n", __FUNCTION__); } return lock; }