Search in sources :

Example 26 with Unpreemptible

use of org.vmmagic.pragma.Unpreemptible in project JikesRVM by JikesRVM.

the class RVMThread method yieldpointFromPrologue.

/*
   * Support for yieldpoints
   */
/**
 * Yieldpoint taken in prologue.
 */
@BaselineSaveLSRegisters
// Save all non-volatile registers in prologue
@NoOptCompile
@NoInline
// TODO fix this -- related to SaveVolatile
@Entrypoint
@Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process")
public static void yieldpointFromPrologue() {
    Address fp = Magic.getFramePointer();
    yieldpoint(PROLOGUE, fp);
}
Also used : Address(org.vmmagic.unboxed.Address) Unpreemptible(org.vmmagic.pragma.Unpreemptible) Entrypoint(org.vmmagic.pragma.Entrypoint) BaselineSaveLSRegisters(org.vmmagic.pragma.BaselineSaveLSRegisters) NoInline(org.vmmagic.pragma.NoInline) NoOptCompile(org.vmmagic.pragma.NoOptCompile)

Example 27 with Unpreemptible

use of org.vmmagic.pragma.Unpreemptible in project JikesRVM by JikesRVM.

the class RVMThread method safeBlock.

@Unpreemptible
private int safeBlock(BlockAdapter ba, boolean asynchronous) {
    if (VM.VerifyAssertions)
        VM._assert(getCurrentThread() != this);
    beginPairWithCurrent();
    int result = block(ba, asynchronous);
    endPairWithCurrent();
    return result;
}
Also used : Entrypoint(org.vmmagic.pragma.Entrypoint) Unpreemptible(org.vmmagic.pragma.Unpreemptible)

Example 28 with Unpreemptible

use of org.vmmagic.pragma.Unpreemptible in project JikesRVM by JikesRVM.

the class RVMThread method checkBlockNoSaveContext.

/**
 * A variant of checkBlock() that does not save the thread state.
 */
@NoInline
@Unpreemptible("May block if the thread was asked to do so, but otherwise does no actions that would cause blocking")
private void checkBlockNoSaveContext() {
    assertUnacceptableStates(NEW, TERMINATED);
    if (VM.VerifyAssertions)
        VM._assert(!isAboutToTerminate);
    if (VM.VerifyAssertions)
        VM._assert(!isBlocking);
    if (traceBlock)
        VM.sysWriteln("Thread #", threadSlot, " in checkBlockNoSaveContext");
    // NB: anything this method calls CANNOT change the contextRegisters
    // or the JNI env. as well, this code will be running concurrently
    // with stop-the-world GC!
    monitor().lockNoHandshake();
    isBlocking = true;
    if (traceBlock)
        VM.sysWriteln("Thread #", threadSlot, " acquired lock and has notified everyone that we're blocked");
    // deal with requests that would require a soft handshake rendezvous
    handleHandshakeRequest();
    // check if a soft handshake has been requested, and if so, clear the
    // request
    boolean commitSoftRendezvous = softRendezvousCheckAndClear();
    if (commitSoftRendezvous) {
        // if a soft handshake had been requested, we need to acknowledge it.
        // but to acknowledge it we cannot be holding the monitor() lock.
        // it turns out that at this point in the code it is perfectly safe
        // to release it, because:
        // 1) callers of this method expect that it may, in all likelihood,
        // release the monitor() lock if they were holding it, since it
        // calls wait()
        // 2) if the block requests get cleared when we release the lock,
        // we won't call wait, since we reacquire the lock prior to checking
        // for block requests.
        int recCount = monitor().unlockCompletely();
        softRendezvousCommit();
        monitor().relockNoHandshake(recCount);
    }
    if (traceBlock)
        VM.sysWriteln("Thread #", threadSlot, " has acknowledged soft handshakes");
    boolean hadReallyBlocked = false;
    for (; ; ) {
        // deal with block requests
        acknowledgeBlockRequests();
        // are we blocked?
        if (!isBlocked()) {
            break;
        }
        if (traceReallyBlock) {
            hadReallyBlocked = true;
            VM.sysWriteln("Thread #", threadSlot, " is really blocked with status ", READABLE_EXEC_STATUS[getExecStatus()]);
            VM.sysWriteln("Thread #", threadSlot, " has fp = ", Magic.getFramePointer());
            if (dumpStackOnBlock) {
                dumpStack();
            }
        }
        // what if a GC request comes while we're here for a suspend()
        // request?
        // answer: we get awoken, reloop, and acknowledge the GC block
        // request.
        monitor().waitNoHandshake();
        if (traceBlock)
            VM.sysWriteln("Thread #", threadSlot, " has awoken; checking if we're still blocked");
    }
    if (traceBlock || (traceReallyBlock && hadReallyBlocked))
        VM.sysWriteln("Thread #", threadSlot, " is unblocking");
    // we're about to unblock, so indicate to the world that we're running
    // again.
    setExecStatus(IN_JAVA);
    // let everyone know that we're back to executing code
    isBlocking = false;
    // deal with requests that came up while we were blocked.
    handleHandshakeRequest();
    monitor().unlock();
    if (traceBlock)
        VM.sysWriteln("Thread #", threadSlot, " is unblocked");
}
Also used : Entrypoint(org.vmmagic.pragma.Entrypoint) Unpreemptible(org.vmmagic.pragma.Unpreemptible) NoInline(org.vmmagic.pragma.NoInline)

Example 29 with Unpreemptible

use of org.vmmagic.pragma.Unpreemptible 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();
}
Also used : Entrypoint(org.vmmagic.pragma.Entrypoint) Unpreemptible(org.vmmagic.pragma.Unpreemptible) NoCheckStore(org.vmmagic.pragma.NoCheckStore)

Example 30 with Unpreemptible

use of org.vmmagic.pragma.Unpreemptible in project JikesRVM by JikesRVM.

the class RVMThread method hardHandshakeSuspend.

@Unpreemptible
@NoCheckStore
public static void hardHandshakeSuspend(BlockAdapter ba, HardHandshakeVisitor hhv) {
    long before = sysCall.sysNanoTime();
    RVMThread current = getCurrentThread();
    handshakeLock.lockWithHandshake();
    int numLockedLocks = 0;
    for (int i = 0; i < nextSlot; ++i) {
        Monitor l = communicationLockBySlot[i];
        if (l != null) {
            l.lockWithHandshake();
            numLockedLocks++;
        }
    }
    // while we're waiting.  that is unlikely but possible.
    for (; ; ) {
        acctLock.lockNoHandshake();
        int numToHandshake = 0;
        for (int i = 0; i < numThreads; ++i) {
            RVMThread t = threads[i];
            if (t != current && !t.ignoreHandshakesAndGC() && hhv.includeThread(t)) {
                handshakeThreads[numToHandshake++] = t;
            }
        }
        acctLock.unlock();
        for (int i = 0; i < numToHandshake; ++i) {
            RVMThread t = handshakeThreads[i];
            t.monitor().lockNoHandshake();
            if (t.blockedFor(ba) || notRunning(t.asyncBlock(ba))) {
                // already blocked or not running, remove
                handshakeThreads[i--] = handshakeThreads[--numToHandshake];
                // help GC
                handshakeThreads[numToHandshake] = null;
            }
            t.monitor().unlock();
        }
        // terminating).
        if (numToHandshake == 0)
            break;
        for (int i = 0; i < numToHandshake; ++i) {
            RVMThread t = handshakeThreads[i];
            observeExecStatusAtSTW(t.block(ba));
            // help GC
            handshakeThreads[i] = null;
        }
    }
    processAboutToTerminate();
    /*
                                * ensure that any threads that died while
                                * we were stopping the world notify us
                                * that they had stopped.
                                */
    int numUnlockedLocks = 0;
    for (int i = 0; i < nextSlot; ++i) {
        Monitor l = communicationLockBySlot[i];
        if (l != null) {
            l.unlock();
            numUnlockedLocks++;
        }
    }
    if (VM.VerifyAssertions)
        VM._assert(numLockedLocks == numUnlockedLocks);
    handshakeLock.unlock();
    if (false) {
        long after = sysCall.sysNanoTime();
        totalSuspendTime += after - before;
        VM.sysWriteln("Stopping the world took ", (after - before), " ns (", totalSuspendTime, " ns total)");
    }
}
Also used : Entrypoint(org.vmmagic.pragma.Entrypoint) Unpreemptible(org.vmmagic.pragma.Unpreemptible) NoCheckStore(org.vmmagic.pragma.NoCheckStore)

Aggregations

Unpreemptible (org.vmmagic.pragma.Unpreemptible)34 Entrypoint (org.vmmagic.pragma.Entrypoint)23 NoInline (org.vmmagic.pragma.NoInline)14 Address (org.vmmagic.unboxed.Address)12 RVMThread (org.jikesrvm.scheduler.RVMThread)7 Offset (org.vmmagic.unboxed.Offset)6 Word (org.vmmagic.unboxed.Word)6 NoCheckStore (org.vmmagic.pragma.NoCheckStore)5 NoNullCheck (org.vmmagic.pragma.NoNullCheck)5 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)4 Inline (org.vmmagic.pragma.Inline)4 BaselineSaveLSRegisters (org.vmmagic.pragma.BaselineSaveLSRegisters)3 NoOptCompile (org.vmmagic.pragma.NoOptCompile)3 NormalMethod (org.jikesrvm.classloader.NormalMethod)2 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)2 GPR (org.jikesrvm.ia32.RegisterConstants.GPR)2 AbstractRegisters (org.jikesrvm.architecture.AbstractRegisters)1 RVMArray (org.jikesrvm.classloader.RVMArray)1 RVMMethod (org.jikesrvm.classloader.RVMMethod)1 RVMType (org.jikesrvm.classloader.RVMType)1