📄 sync.c
字号:
#ifdef CVM_DEBUG CVMassert(m->nextOwned == NULL && m->rmutex.owner == NULL);#endif}CVMBoolCVMsysMutexTryLock(CVMExecEnv * ee, CVMSysMutex * m){ CVMBool success; CVMtraceSysMutex(("CVMsysMutexTryLock(%s)\n", m->name));#ifdef CVM_DEBUG CVMassert(ee->microLock == 0); /* no locking while holding microlock */ CVMassert(ee->sysLocks == NULL || m->rmutex.owner == ee || m->rank > ee->sysLocks->rank);#endif success = CVMreentrantMutexTryLock(ee, &m->rmutex);#ifdef CVM_DEBUG if (success && CVMsysMutexCount(m) == 1) { m->nextOwned = ee->sysLocks; ee->sysLocks = m; }#endif return success;}voidCVMsysMutexLock(CVMExecEnv * ee, CVMSysMutex * m){ CVMtraceSysMutex(("CVMsysMutexLock(\"%s\")\n", m->name));#ifdef CVM_DEBUG /* no locking while holding a microlock */ CVMassert(ee->microLock == 0 || m->rmutex.owner == ee); CVMassert(ee->sysLocks == NULL || m->rmutex.owner == ee || m->rank > ee->sysLocks->rank);#endif CVMreentrantMutexLock(ee, &m->rmutex);#ifdef CVM_DEBUG if (CVMsysMutexCount(m) == 1) { m->nextOwned = ee->sysLocks; ee->sysLocks = m; }#endif}voidCVMsysMutexUnlock(CVMExecEnv * ee, CVMSysMutex * m){ CVMtraceSysMutex(("CVMsysMutexUnlock(\"%s\")\n", m->name));#ifdef CVM_DEBUG CVMassert(CVMsysMutexCount(m) > 1 || ee->sysLocks == m); if (CVMsysMutexCount(m) == 1) { ee->sysLocks = m->nextOwned; m->nextOwned = NULL; }#endif CVMreentrantMutexUnlock(ee, &m->rmutex);}/* * CVM_FALSE is returned to indicate that the wait was interrupted, * otherwise CVM_TRUE is returned. */CVMBoolCVMsysMutexWait(CVMExecEnv * ee, CVMSysMutex *m, CVMCondVar * c, CVMInt64 millis){ CVMBool ret;#ifdef CVM_DEBUG CVMassert(ee->sysLocks == m); ee->sysLocks = ee->sysLocks->nextOwned;#endif ret = CVMreentrantMutexWait(ee, &m->rmutex, c, millis);#ifdef CVM_DEBUG m->nextOwned = ee->sysLocks; ee->sysLocks = m;#endif return ret;}#ifdef CVM_DEBUGvoidCVMsysMicroLock(CVMExecEnv *ee, CVMSysMicroLock l){ CVMassert(++ee->microLock == 1); CVMsysMicroLockImpl(l);}voidCVMsysMicroUnlock(CVMExecEnv *ee, CVMSysMicroLock l){ CVMassert(--ee->microLock == 0); CVMsysMicroUnlockImpl(l);}#endif /* CVM_DEBUG *//* * Acquire all the microlocks. Don't do anything for SCHEDLOCK because * the fact that this thread is running implies that no other thread * has acquired any of the microlocks. */voidCVMsysMicroLockAll(CVMExecEnv *ee){#if CVM_MICROLOCK_TYPE != CVM_MICROLOCK_SCHEDLOCK int i; for (i = 0; i < CVM_NUM_SYS_MICROLOCKS; i++) { CVMsysMicroLockImpl(i); }#endif}voidCVMsysMicroUnlockAll(CVMExecEnv *ee){#if CVM_MICROLOCK_TYPE != CVM_MICROLOCK_SCHEDLOCK int i; for (i = CVM_NUM_SYS_MICROLOCKS - 1; i >= 0; i--) { CVMsysMicroUnlockImpl(i); }#endif}/*===========================================================================*/#if defined(CVM_JVMPI) || defined(CVM_JVMTI)/* Purpose: Constructor. */CVMBool CVMprofiledMonitorInit(CVMProfiledMonitor *self, CVMExecEnv *owner, CVMUint32 count, CVMUint8 lockType){ if (CVMsysMonitorInit(&self->_super, owner, count)) { CVMprofiledMonitorSetType(self, lockType); self->contentionCount = 0; return CVM_TRUE; } return CVM_FALSE;}/* gcc 3.2 complains about ifdefs inside a macro */static void postContendedEnter(CVMProfiledMonitor *self, CVMExecEnv *ee) {#ifdef CVM_JVMPI if (CVMjvmpiEventMonitorContendedEnterIsEnabled()) { CVMjvmpiPostMonitorContendedEnterEvent(ee, self); }#endif#ifdef CVM_JVMTI ee->threadState = CVM_THREAD_BLOCKED_MONITOR_ENTER; if (CVMjvmtiShouldPostMonitorContendedEnter()) { CVMjvmtiPostMonitorContendedEnterEvent(ee, self); }#endif}static void postContendedEntered(CVMProfiledMonitor *self, CVMExecEnv *ee) {#ifdef CVM_JVMPI if (CVMjvmpiEventMonitorContendedEnteredIsEnabled()) { CVMjvmpiPostMonitorContendedEnteredEvent(ee, self); }#endif#ifdef CVM_JVMTI if (CVMjvmtiShouldPostMonitorContendedEntered()) { CVMjvmtiPostMonitorContendedEnteredEvent(ee, self); }#endif}/* Purpose: Enters the specified monitor. */void CVMprofiledMonitorEnterSafe(CVMProfiledMonitor *self, CVMExecEnv *ee, CVMBool doPost){ CVMReentrantMutex *rm = &self->_super.rmutex; CVMassert(CVMD_isgcSafe(ee)); CVMassert(self->type != CVM_LOCKTYPE_UNKNOWN); CVMreentrantMutexDoLock(rm, ee, { /* Locking action: */ CVMBool hasContention = CVM_FALSE; CVMsysMicroLock(ee, CVM_TOOLS_MICROLOCK); if (!CVMmutexTryLock(&rm->mutex)) { self->contentionCount++; hasContention = CVM_TRUE; } CVMsysMicroUnlock(ee, CVM_TOOLS_MICROLOCK); if (hasContention) { ee->blockingLockEntryMonitor = self; if (doPost) { postContendedEnter(self, ee); } CVMmutexLock(&rm->mutex); ee->blockingLockEntryMonitor = NULL; if (doPost) { postContendedEntered(self, ee); } } });}#ifdef CVM_THREAD_BOOST/* This operation is done before thread boosting */voidCVMprofiledMonitorPreContendedEnterUnsafe(CVMProfiledMonitor *self, CVMExecEnv *ee){ CVMsysMicroLock(ee, CVM_TOOLS_MICROLOCK); self->contentionCount++; CVMsysMicroUnlock(ee, CVM_TOOLS_MICROLOCK); CVMD_gcSafeExec((ee), { ee->blockingLockEntryMonitor = self; postContendedEnter(self, ee); });}/* This operation is done after thread boosting */voidCVMprofiledMonitorContendedEnterUnsafe(CVMProfiledMonitor *self, CVMExecEnv *ee){ CVMReentrantMutex *rm = &self->_super.rmutex; CVMassert(CVMD_isgcUnsafe(ee)); CVMassert(self->type != CVM_LOCKTYPE_UNKNOWN); CVMreentrantMutexDoLock(rm, ee, { /* Locking action: */ CVMD_gcSafeExec((ee), { CVMmutexLock(&(rm)->mutex); ee->blockingLockEntryMonitor = NULL; postContendedEntered(self, ee); }); });}#endif/* Purpose: Enters the specified monitor. Assumes that the current thread is in a GC safe state. */void CVMprofiledMonitorEnterUnsafe(CVMProfiledMonitor *self, CVMExecEnv *ee, CVMBool doPost){ CVMReentrantMutex *rm = &self->_super.rmutex; CVMassert(CVMD_isgcUnsafe(ee)); CVMassert(self->type != CVM_LOCKTYPE_UNKNOWN); CVMreentrantMutexDoLock(rm, ee, { /* Locking action: */ CVMBool hasContention = CVM_FALSE; CVMsysMicroLock(ee, CVM_TOOLS_MICROLOCK); if (!CVMmutexTryLock(&rm->mutex)) { self->contentionCount++; hasContention = CVM_TRUE; } CVMsysMicroUnlock(ee, CVM_TOOLS_MICROLOCK); if (hasContention) { CVMD_gcSafeExec((ee), { ee->blockingLockEntryMonitor = self; if (doPost) { postContendedEnter(self, ee); } CVMmutexLock(&(rm)->mutex); ee->blockingLockEntryMonitor = NULL; if (doPost) { postContendedEntered(self, ee); } }); } });}static void profileMonitorExit(CVMProfiledMonitor *self, CVMExecEnv *ee, CVMBool hasContention) {#ifdef CVM_JVMTI (void)hasContention; ee->threadState &= ~CVM_THREAD_BLOCKED_MONITOR_ENTER;#endif#ifdef CVM_JVMPI if (hasContention && CVMjvmpiEventMonitorContendedExitIsEnabled()) { CVMjvmpiPostMonitorContendedExitEvent(ee, self); }#endif}/* Purpose: Exits the specified monitor. */void CVMprofiledMonitorExit(CVMProfiledMonitor *self, CVMExecEnv *ee){ CVMReentrantMutex *rm = &self->_super.rmutex; CVMassert(self->type != CVM_LOCKTYPE_UNKNOWN); CVMreentrantMutexDoUnlock(rm, ee, { /* Unlock action: */ CVMBool hasContention = CVM_FALSE; CVMmutexUnlock(&rm->mutex); CVMsysMicroLock(ee, CVM_TOOLS_MICROLOCK); if (self->contentionCount > 0) { self->contentionCount--; hasContention = CVM_TRUE; } CVMsysMicroUnlock(ee, CVM_TOOLS_MICROLOCK); profileMonitorExit(self, ee, hasContention); });}/* Purpose: Wait for the specified time period (in milliseconds). If the period is 0, then wait forever. *//* Returns: CVM_WAIT_NOT_OWNER if current_ee is not the owner of the monitor, CVM_WAIT_OK if the thread was woken up by a timeout, and CVM_WAIT_INTERRUPTED is the thread was woken up by a notify. *//* NOTE: Thread must be in a GC safe state before calling this. */CVMWaitStatusCVMprofiledMonitorWait(CVMProfiledMonitor *self, CVMExecEnv *ee, CVMInt64 millis){ CVMSysMonitor *mon = &self->_super; CVMWaitStatus result; CVMassert(CVMD_isgcSafe(ee)); CVMsysMonitorDoWait(mon, ee, result, { CVMReentrantMutex *rm = &mon->rmutex; CVMreentrantMutexDoWait(rm, ee, { ee->blockingWaitMonitor = self; waitActionResult = CVMcondvarWait(&mon->condvar, &rm->mutex, millis); ee->blockingWaitMonitor = NULL; }); }); return result;}#endif /* CVM_JVMPI || CVM_JVMTI */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -