Beispiel #1
0
  @TruffleBoundary
  private SafepointAction step(Node currentNode, boolean isDrivingThread) {
    final DynamicObject thread = context.getThreadManager().getCurrentThread();

    // wait other threads to reach their safepoint
    phaser.arriveAndAwaitAdvance();

    if (isDrivingThread) {
      assumption = Truffle.getRuntime().createAssumption("SafepointManager");
    }

    // wait the assumption to be renewed
    phaser.arriveAndAwaitAdvance();

    // Read these while in the safepoint.
    SafepointAction deferredAction = deferred ? action : null;

    try {
      if (!deferred && thread != null && Layouts.THREAD.getStatus(thread) != Status.ABORTING) {
        action.run(thread, currentNode);
      }
    } finally {
      // wait other threads to finish their action
      phaser.arriveAndAwaitAdvance();
    }

    return deferredAction;
  }
Beispiel #2
0
  @TruffleBoundary
  private void assumptionInvalidated(Node currentNode, boolean fromBlockingCall) {
    final DynamicObject thread = context.getThreadManager().getCurrentThread();
    final InterruptMode interruptMode = Layouts.THREAD.getInterruptMode(thread);

    final boolean interruptible =
        (interruptMode == InterruptMode.IMMEDIATE)
            || (fromBlockingCall && interruptMode == InterruptMode.ON_BLOCKING);

    if (!interruptible) {
      Thread.currentThread().interrupt(); // keep the interrupt flag
      return; // interrupt me later
    }

    SafepointAction deferredAction = step(currentNode, false);

    // We're now running again normally and can run deferred actions
    if (deferredAction != null) {
      deferredAction.run(thread, currentNode);
    }
  }
Beispiel #3
0
 @TruffleBoundary
 public void pauseThreadAndExecuteLater(
     final Thread thread, Node currentNode, final SafepointAction action) {
   if (Thread.currentThread() == thread) {
     // fast path if we are already the right thread
     DynamicObject rubyThread = context.getThreadManager().getCurrentThread();
     action.run(rubyThread, currentNode);
   } else {
     pauseAllThreadsAndExecute(
         currentNode,
         true,
         new SafepointAction() {
           @Override
           public void run(DynamicObject rubyThread, Node currentNode) {
             if (Thread.currentThread() == thread) {
               action.run(rubyThread, currentNode);
             }
           }
         });
   }
 }
Beispiel #4
0
  @TruffleBoundary
  public void pauseAllThreadsAndExecute(
      Node currentNode, boolean deferred, SafepointAction action) {
    if (lock.isHeldByCurrentThread()) {
      throw new IllegalStateException("Re-entered SafepointManager");
    }

    // Need to lock interruptibly since we are in the registered threads.
    while (!lock.tryLock()) {
      poll(currentNode);
    }

    try {
      pauseAllThreadsAndExecute(currentNode, true, action, deferred);
    } finally {
      lock.unlock();
    }

    // Run deferred actions after leaving the SafepointManager lock.
    if (deferred) {
      action.run(context.getThreadManager().getCurrentThread(), currentNode);
    }
  }