use of org.vmmagic.pragma.NoCheckStore in project JikesRVM by JikesRVM.
the class RVMThread method snapshotHandshakeThreads.
@NoCheckStore
public static int snapshotHandshakeThreads(SoftHandshakeVisitor v) {
// figure out which threads to consider
// get a consistent view of which threads are live.
acctLock.lockNoHandshake();
int numToHandshake = 0;
for (int i = 0; i < numThreads; ++i) {
RVMThread t = threads[i];
// -the threads that the provided visitor does not want to include
if (t != RVMThread.getCurrentThread() && !t.ignoreHandshakesAndGC() && !t.isCollectorThread() && v.includeThread(t)) {
handshakeThreads[numToHandshake++] = t;
}
}
acctLock.unlock();
return numToHandshake;
}
use of org.vmmagic.pragma.NoCheckStore in project JikesRVM by JikesRVM.
the class RVMThread method checkDebugRequest.
@NoCheckStore
public static void checkDebugRequest() {
if (debugRequested) {
debugLock.lockNoHandshake();
if (debugRequested) {
debugRequested = false;
VM.sysWriteln("=== Debug requested - attempting safe VM dump ===");
dumpAcct();
reportThreadTransitionCounts();
// FIXME: this code runs concurrently to GC and has no way of stopping
// it. hence it is dangerous. leaving it as-is for now, since it's
// only meant to be used for debugging.
VM.sysWriteln("Timer ticks = ", timerTicks);
doProfileReport.openNoHandshake();
// snapshot the threads
acctLock.lockNoHandshake();
int numDebugThreads = numThreads;
for (int i = 0; i < numThreads; ++i) {
debugThreads[i] = threads[i];
}
acctLock.unlock();
// do the magic
for (int i = 0; i < numDebugThreads; ++i) {
debugThreads[i].handleDebugRequestForThread();
debugThreads[i] = null;
}
}
debugLock.unlock();
}
}
use of org.vmmagic.pragma.NoCheckStore in project JikesRVM by JikesRVM.
the class RVMThread method unblockAllMutatorsForGC.
/**
* Unblock all mutators blocked for GC.
*/
@NoCheckStore
@Unpreemptible
public static void unblockAllMutatorsForGC() {
RVMThread.handshakeLock.lockNoHandshake();
RVMThread.acctLock.lockNoHandshake();
int numToHandshake = 0;
for (int i = 0; i < RVMThread.numThreads; i++) {
RVMThread t = RVMThread.threads[i];
if (!t.isCollectorThread() && !t.ignoreHandshakesAndGC()) {
RVMThread.handshakeThreads[numToHandshake++] = t;
}
}
RVMThread.acctLock.unlock();
for (int i = 0; i < numToHandshake; i++) {
RVMThread.handshakeThreads[i].unblock(RVMThread.gcBlockAdapter);
// Help GC
RVMThread.handshakeThreads[i] = null;
}
RVMThread.handshakeLock.unlock();
}
use of org.vmmagic.pragma.NoCheckStore in project JikesRVM by JikesRVM.
the class RVMThread method blockAllMutatorsForGC.
/**
* Stop all mutator threads. This is current intended to be run by a single thread.
*
* Fixpoint until there are no threads that we haven't blocked. Fixpoint is needed to
* catch the (unlikely) case that a thread spawns another thread while we are waiting.
*/
@NoCheckStore
@Unpreemptible
public static void blockAllMutatorsForGC() {
RVMThread.handshakeLock.lockNoHandshake();
while (true) {
// (1) Find all the threads that need to be blocked for GC
RVMThread.acctLock.lockNoHandshake();
int numToHandshake = 0;
for (int i = 0; i < RVMThread.numThreads; i++) {
RVMThread t = RVMThread.threads[i];
if (!t.isCollectorThread() && !t.ignoreHandshakesAndGC()) {
RVMThread.handshakeThreads[numToHandshake++] = t;
}
}
RVMThread.acctLock.unlock();
// (2) Remove any threads that have already been blocked from the list.
for (int i = 0; i < numToHandshake; i++) {
RVMThread t = RVMThread.handshakeThreads[i];
t.monitor().lockNoHandshake();
if (t.blockedFor(RVMThread.gcBlockAdapter) || RVMThread.notRunning(t.asyncBlock(RVMThread.gcBlockAdapter))) {
// Already blocked or not running, remove.
RVMThread.handshakeThreads[i--] = RVMThread.handshakeThreads[--numToHandshake];
// help GC
RVMThread.handshakeThreads[numToHandshake] = null;
}
t.monitor().unlock();
}
// terminating).
if (numToHandshake == 0)
break;
// (4) Request a block for GC from all other threads.
for (int i = 0; i < numToHandshake; i++) {
if (false)
VM.sysWriteln("Waiting for ", RVMThread.handshakeThreads[i].getThreadSlot(), " to block.");
RVMThread t = RVMThread.handshakeThreads[i];
RVMThread.observeExecStatusAtSTW(t.block(RVMThread.gcBlockAdapter));
// help GC
RVMThread.handshakeThreads[i] = null;
}
}
RVMThread.handshakeLock.unlock();
// Deal with terminating threads to ensure that all threads are either dead to MMTk or stopped above.
RVMThread.processAboutToTerminate();
}
use of org.vmmagic.pragma.NoCheckStore in project JikesRVM by JikesRVM.
the class RVMThread method softHandshake.
/**
* Tell each thread to take a yieldpoint and wait until all of them have done
* so at least once. Additionally, call the visitor on each thread when making
* the yieldpoint request; the purpose of the visitor is to set any additional
* fields as needed to make specific requests to the threads that yield. Note
* that the visitor's <code>visit()</code> method is called with both the
* thread's monitor held, and the <code>softHandshakeDataLock</code> held.
* <p>
* Currently we only use this mechanism for code patch isync requests on PPC,
* but this mechanism is powerful enough to be used by sliding-views style
* concurrent GC.
*
* @param v the visitor to use for the handshake
*/
@NoCheckStore
@Unpreemptible("Does not perform actions that lead to blocking, but may wait for threads to rendezvous with the soft handshake")
public static void softHandshake(SoftHandshakeVisitor v) {
handshakeLock.lockWithHandshake();
/*
* prevent multiple (soft or hard) handshakes
* from proceeding concurrently
*/
int numToHandshake = snapshotHandshakeThreads(v);
if (VM.VerifyAssertions)
VM._assert(softHandshakeLeft == 0);
// request one
for (int i = 0; i < numToHandshake; ++i) {
RVMThread t = handshakeThreads[i];
// help GC
handshakeThreads[i] = null;
t.monitor().lockNoHandshake();
boolean waitForThisThread = false;
if (!t.isAboutToTerminate && v.checkAndSignal(t)) {
// CAS the execStatus field
t.setBlockedExecStatus();
// confident that the thread's state is blocked from changing.
if (t.isInJava()) {
// the thread is currently executing Java code, so we must ensure
// that it either:
// 1) takes the next yieldpoint and rendezvous with this soft
// handshake request (see yieldpoint), or
// 2) performs the rendezvous when leaving Java code
// (see enterNativeBlocked, checkBlock, and addAboutToTerminate)
// either way, we will wait for it to get there before exiting
// this call, since the caller expects that after softHandshake()
// returns, no thread will be running Java code without having
// acknowledged.
t.softHandshakeRequested = true;
t.takeYieldpoint = 1;
waitForThisThread = true;
} else {
// the thread is not in Java code (it may be blocked or it may be
// in native), so we don't have to wait for it since it will
// do the Right Thing before returning to Java code. essentially,
// the thread cannot go back to running Java without doing whatever
// was requested because:
// A) we've set the execStatus to blocked, and
// B) we're holding its lock.
v.notifyStuckInNative(t);
}
}
t.monitor().unlock();
if (waitForThisThread) {
softHandshakeDataLock.lockNoHandshake();
softHandshakeLeft++;
softHandshakeDataLock.unlock();
}
}
// wait for all threads to reach the handshake
softHandshakeDataLock.lockNoHandshake();
if (VM.VerifyAssertions)
VM._assert(softHandshakeLeft >= 0);
while (softHandshakeLeft > 0) {
// wait and tell the world that we're off in native land. this way
// if someone tries to block us at this point (suspend() or GC),
// they'll know not to wait for us.
softHandshakeDataLock.waitWithHandshake();
}
if (VM.VerifyAssertions)
VM._assert(softHandshakeLeft == 0);
softHandshakeDataLock.unlock();
processAboutToTerminate();
handshakeLock.unlock();
}
Aggregations