cstates.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 319 行
C
319 行
/* * @(#)cstates.c 1.37 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */#include "javavm/include/cstates.h"#include "javavm/include/globals.h"#include "javavm/include/interpreter.h"#include "javavm/include/utils.h"#include "javavm/include/porting/doubleword.h"#ifdef CVM_JIT#include "javavm/include/porting/jit/jit.h"#endif#ifdef CVM_HW#include "include/hw.h"#endifCVMBoolCVMcsInit(CVMCState *cs, const char *nm, CVMUint8 rank){ cs->request = CVM_FALSE; cs->count = 0; cs->reached = CVM_FALSE; cs->requester = NULL; cs->name = nm; if (CVMsysMutexInit(&cs->mutex, nm, rank)) { if (CVMcondvarInit(&cs->consistentCV, &cs->mutex.rmutex.mutex)) { if (!CVMcondvarInit(&cs->resumeCV, &cs->mutex.rmutex.mutex)) { goto bad0; } } else { goto bad1; } } return CVM_TRUE;bad0: CVMcondvarDestroy(&cs->consistentCV);bad1: CVMsysMutexDestroy(&cs->mutex); return CVM_FALSE;}voidCVMcsDestroy(CVMCState *cs){ CVMcondvarDestroy(&cs->consistentCV); CVMcondvarDestroy(&cs->resumeCV); CVMsysMutexDestroy(&cs->mutex);}/* * Bring all other threads to a consistent state. */voidCVMcsReachConsistentState(CVMExecEnv *ee, CVMCStateID csID){ CVMCState *cs = CVM_CSTATE(csID); /* Check that current thread is consistent */ CVMassert(CVMcsIsConsistent(CVM_TCSTATE(ee, csID))); /* and that a request hasn't already been made */ CVMassert(!CVMcsCheckRequest(cs)); /* and that the threadLock has been acquired */ CVMassert(CVMsysMutexIAmOwner(ee, &CVMglobals.threadLock)); CVMsysMutexLock(ee, &cs->mutex); CVMassert(cs->requester == NULL); cs->requester = ee; ++cs->count; CVMassert(!cs->reached); CVMtraceCS(("<%d> CS<%d>: ee=0x%x, reaching consistent state %s\n", ee->threadID, cs->count, ee, cs->name)); cs->inconsistentThreadCount = 0; cs->request = CVM_TRUE;#ifdef CVM_MP_SAFE /* * On a multi-processor system, we need to use a * memory barrier to make sure changes are visible to all threads. */ CVMmemoryBarrier();#endif /* * After the request is set, threads will only transition from * unsafe to safe, so it is OK to check the per-thread state * without a lock and before we suspend it. */ /* Roll other threads forward if necessary */ { CVM_WALK_ALL_THREADS(ee, targetEE, { if (targetEE != ee) { CVMTCState *tcs = CVM_TCSTATE(targetEE, csID); CVMUint32 suspended = targetEE->threadState & CVM_THREAD_SUSPENDED; /* * Check the state while the thread is running. * State variable needs to be volatile and consistent * with regard to cs->request (MP systems). * * A suspended thread is consistent, even though * its state may be in flux if it was at a * transition. */ tcs->wasConsistent = CVMcsIsConsistent(tcs); if (suspended || tcs->wasConsistent) { /* thread is OK */ CVMtraceCS(("<%d> CS<%d>: %s thread <%d>\n", ee->threadID, cs->count, suspended ? "suspended" : "consistent", targetEE->threadID)); } else { ++cs->inconsistentThreadCount; CVMtraceCS(("<%d> CS<%d>: inconsistent thread <%d>\n", ee->threadID, cs->count, targetEE->threadID)); } } }); }#ifdef CVM_JIT#if defined(CVMJIT_PATCH_BASED_GC_CHECKS) || defined(CVMJIT_TRAP_BASED_GC_CHECKS) if (cs->inconsistentThreadCount > 0) { /* enable rendezvous calls in compiled methods */ CVMJITenableRendezvousCalls(ee); CVMglobals.jit.csNeedDisable = CVM_TRUE; } else { CVMglobals.jit.csNeedDisable = CVM_FALSE; }#endif#endif#ifdef CVM_HW CVMhwRequestConsistentState();#endif { CVMBool interrupted = CVM_FALSE; while (cs->inconsistentThreadCount > 0) { if (!CVMsysMutexWait(ee, &cs->mutex, &cs->consistentCV, CVMlongConstZero())) { interrupted = CVM_TRUE; } } if (interrupted) { CVMtraceCS(("<%d> CS<%d>: interrupted!\n", ee->threadID, cs->count)); CVMthreadInterruptWait(CVMexecEnv2threadID(ee)); } } CVMtraceCS(("<%d> CS<%d>: done waiting for count to reach 0\n", ee->threadID, cs->count)); cs->reached = CVM_TRUE; CVMsysMutexUnlock(ee, &cs->mutex); CVMtraceCS(("<%d> CS<%d>: mutex unlocked\n", ee->threadID, cs->count));}/* * Allow other threads to become inconsistent again. */voidCVMcsResumeConsistentState(CVMExecEnv *ee, CVMCStateID csID){ CVMCState *cs = CVM_CSTATE(csID); CVMtraceCS(("<%d> CS<%d>: ee=0x%x, resuming consistent state %s\n", ee->threadID, cs->count, ee, cs->name)); cs->reached = CVM_FALSE; CVMassert(cs->requester == ee); cs->requester = NULL; CVMsysMutexLock(ee, &cs->mutex); cs->request = CVM_FALSE;#ifdef CVM_JIT#if defined(CVMJIT_PATCH_BASED_GC_CHECKS) || defined(CVMJIT_TRAP_BASED_GC_CHECKS) /* disable gc rendezvous checkpoints for compiled methods */ if (CVMglobals.jit.csNeedDisable) { CVMJITdisableRendezvousCalls(ee); }#endif#endif#ifdef CVM_HW CVMhwReleaseConsistentState();#endif CVMcondvarNotifyAll(&cs->resumeCV); CVMsysMutexUnlock(ee, &cs->mutex);}/* * Rendezvous with the requestor thread. We block only if "block" is * set to true. */voidCVMcsRendezvous(CVMExecEnv *ee, CVMCState *cs, CVMTCState *tcs, CVMBool block){ CVMBool isConsistent = tcs->isConsistent; CVMUint32 count; /* The requester should not be making transitions during the request */ CVMassert(cs->requester != ee); /* must block if inconsistent */ CVMassert(block != isConsistent); /* Force safe-->unsafe transition to appear safe */ tcs->isConsistent = CVM_TRUE;#ifdef CVM_MP_SAFE /* * On a multi-processor system, we need to use a * memory barrier to make sure changes are visible to all threads. * This is probably overkill here because typically the * mutex lock below will guarantee write consistency. */ CVMmemoryBarrier();#endif CVMsysMutexLock(ee, &cs->mutex); count = cs->count; CVMtraceCS(("<%d> CS<%d>: ee=0x%x, performing rendezvous for " "consistent state %s\n", ee->threadID, count, ee, cs->name)); CVMtraceCS(("<%d> CS<%d>: ee=0x%x, isConsistent %d (%d)" " block? %d request? %d\n", ee->threadID, count, ee, isConsistent, tcs->wasConsistent, block, CVMcsCheckRequest(cs))); if (!tcs->wasConsistent) { CVMassert(CVMcsCheckRequest(cs)); CVMassert(cs->inconsistentThreadCount > 0); tcs->wasConsistent = CVM_TRUE; --cs->inconsistentThreadCount; CVMtraceCS(("<%d> CS<%d>: decrementing count to %d \n", ee->threadID, count, cs->inconsistentThreadCount)); if (cs->inconsistentThreadCount == 0) { CVMtraceCS(("<%d> CS<%d>: performing notify\n", ee->threadID, count)); /* notify condition variable thread */ CVMcondvarNotify(&cs->consistentCV); } } /* still on current cycle? */ CVMassert(count == cs->count); if (block) { CVMBool interrupted = CVM_FALSE; while (CVMcsCheckRequest(cs)) { CVMtraceCS(("<%d> CS<%d>: blocking\n", ee->threadID, cs->count)); if (!CVMsysMutexWait(ee, &cs->mutex, &cs->resumeCV, CVMlongConstZero())) { interrupted = CVM_TRUE; } } if (interrupted) { CVMtraceCS(("<%d> CS<%d>: interrupted!\n", ee->threadID, cs->count)); CVMthreadInterruptWait(CVMexecEnv2threadID(ee)); } CVMtraceCS(("<%d> CS<%d>: done blocking\n", ee->threadID, count)); } else { CVMtraceCS(("<%d> CS<%d>: not blocking\n", ee->threadID, count)); } tcs->isConsistent = isConsistent; CVMtraceCS(("<%d> CS<%d>: isConsistent reset to %d\n", ee->threadID, count, isConsistent)); /* Shouldn't be inconsistent if consistent state was reached */ CVMassert(isConsistent || !cs->reached); CVMtraceCS(("<%d> CS<%d>: resuming execution with isConsistent %d\n", ee->threadID, cs->count, tcs->isConsistent)); CVMsysMutexUnlock(ee, &cs->mutex); /* Shouldn't be inconsistent if consistent state was reached */ CVMassert(isConsistent || !cs->reached);}const char * const CVMcstateNames[CVM_NUM_CONSISTENT_STATES] = { "gc-safe" /* CVM_GC_SAFE */};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?