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; }