< prev index next >
src/java.base/share/classes/java/lang/Thread.java
Print this page
rev 50306 : imported patch loom-fibers
rev 50307 : [mq]: cont
*** 33,42 ****
--- 33,43 ----
import java.security.PrivilegedAction;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
import sun.nio.ch.Interruptible;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import sun.security.util.SecurityConstants;
*** 198,207 ****
--- 199,213 ----
/*
* Thread ID
*/
private final long tid;
+ /*
+ * Current inner-most continuation
+ */
+ private Continuation cont;
+
/* For generating thread ID */
private static long threadSeqNumber;
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
*** 255,266 ****
/**
* Returns a reference to the currently executing thread object.
*
* @return the currently executing thread.
*/
@HotSpotIntrinsicCandidate
! public static native Thread currentThread();
/**
* A hint to the scheduler that the current thread is willing to yield
* its current use of a processor. The scheduler is free to ignore this
* hint.
--- 261,305 ----
/**
* Returns a reference to the currently executing thread object.
*
* @return the currently executing thread.
*/
+ public static Thread currentThread() {
+ Thread t = currentThread0();
+ Fiber fiber = t.fiber;
+ if (fiber != null) {
+ return fiber;
+ } else {
+ return t;
+ }
+ }
+
+ static Thread currentKernelThread() {
+ return currentThread0();
+ }
+
@HotSpotIntrinsicCandidate
! private static native Thread currentThread0();
!
! /**
! * Binds this thread to given Fiber. Once set, Thread.currentThread() will
! * return the Fiber rather than the Thread object for the kernel thread.
! */
! void setFiber(Fiber fiber) {
! assert this == currentThread0();
! this.fiber = fiber;
! }
!
! /**
! * Returns the Fiber that is currently bound to this thread.
! */
! Fiber getFiber() {
! assert this == currentThread0();
! return fiber;
! }
!
! private Fiber fiber;
/**
* A hint to the scheduler that the current thread is willing to yield
* its current use of a processor. The scheduler is free to ignore this
* hint.
*** 293,303 ****
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
! public static native void sleep(long millis) throws InterruptedException;
/**
* Causes the currently executing thread to sleep (temporarily cease
* execution) for the specified number of milliseconds plus the specified
* number of nanoseconds, subject to the precision and accuracy of system
--- 332,362 ----
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
! public static void sleep(long millis) throws InterruptedException {
! if (millis < 0) {
! throw new IllegalArgumentException("timeout value is negative");
! }
! Thread t = Thread.currentThread();
! if (t instanceof Fiber) {
! long nanos = TimeUnit.NANOSECONDS.convert(millis, TimeUnit.MILLISECONDS);
! do {
! long startTime = System.nanoTime();
! Fiber.parkNanos(nanos);
! if (t.getAndClearInterrupt())
! throw new InterruptedException();
! nanos -= System.nanoTime() - startTime;
! } while (nanos > 0);
! } else {
! // regular thread
! sleep0(millis);
! }
! }
!
! private static native void sleep0(long millis) throws InterruptedException;
/**
* Causes the currently executing thread to sleep (temporarily cease
* execution) for the specified number of milliseconds plus the specified
* number of nanoseconds, subject to the precision and accuracy of system
*** 452,461 ****
--- 511,527 ----
/* Set thread ID */
this.tid = nextThreadID();
}
/**
+ * Creates a new Thread that optionally inherits thread locals.
+ */
+ Thread(ThreadGroup group, String name, AccessControlContext acc, boolean inheritThreadLocals) {
+ this(group, null, name, 0, acc, inheritThreadLocals);
+ }
+
+ /**
* Throws CloneNotSupportedException as a Thread can not be meaningfully
* cloned. Construct a new Thread instead.
*
* @throws CloneNotSupportedException
* always
*** 889,898 ****
--- 955,965 ----
* application if the uncaught exception is an instance of
* {@code ThreadDeath}.
*
* @throws SecurityException if the current thread cannot
* modify this thread.
+ * @throws UnsupportedOperationException if the current thread is a fiber
* @see #interrupt()
* @see #checkAccess()
* @see #run()
* @see #start()
* @see ThreadDeath
*** 925,934 ****
--- 992,1005 ----
checkAccess();
if (this != Thread.currentThread()) {
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
+
+ if (this instanceof Fiber)
+ throw new UnsupportedOperationException();
+
// A zero status value corresponds to "NEW", it can't change to
// not-NEW because we hold the lock.
if (threadStatus != 0) {
resume(); // Wake up thread if it was suspended; no-op otherwise
}
*** 1002,1020 ****
// thread may be blocked in an I/O operation
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
! interrupt0(); // set interrupt status
b.interrupt(this);
return;
}
}
}
! // set interrupt status
! interrupt0();
}
/**
* Tests whether the current thread has been interrupted. The
* <i>interrupted status</i> of the thread is cleared by this method. In
--- 1073,1090 ----
// thread may be blocked in an I/O operation
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
! doInterrupt();
b.interrupt(this);
return;
}
}
}
! doInterrupt();
}
/**
* Tests whether the current thread has been interrupted. The
* <i>interrupted status</i> of the thread is cleared by this method. In
*** 1031,1041 ****
* {@code false} otherwise.
* @see #isInterrupted()
* @revised 6.0
*/
public static boolean interrupted() {
! return currentThread().isInterrupted(true);
}
/**
* Tests whether this thread has been interrupted. The <i>interrupted
* status</i> of the thread is unaffected by this method.
--- 1101,1111 ----
* {@code false} otherwise.
* @see #isInterrupted()
* @revised 6.0
*/
public static boolean interrupted() {
! return currentThread().getAndClearInterrupt();
}
/**
* Tests whether this thread has been interrupted. The <i>interrupted
* status</i> of the thread is unaffected by this method.
*** 1052,1067 ****
public boolean isInterrupted() {
return isInterrupted(false);
}
/**
* Tests if some Thread has been interrupted. The interrupted state
! * is reset or not based on the value of ClearInterrupted that is
* passed.
*/
@HotSpotIntrinsicCandidate
! private native boolean isInterrupted(boolean ClearInterrupted);
/**
* Throws {@link NoSuchMethodError}.
*
* @deprecated This method was originally designed to destroy this
--- 1122,1151 ----
public boolean isInterrupted() {
return isInterrupted(false);
}
/**
+ * Invoked by interrupt to set the interrupt status and unpark the thread.
+ */
+ void doInterrupt() {
+ interrupt0();
+ }
+
+ /**
+ * Clears the interrupt status and returns the old value.
+ */
+ boolean getAndClearInterrupt() {
+ return isInterrupted(true);
+ }
+
+ /**
* Tests if some Thread has been interrupted. The interrupted state
! * is reset or not based on the value of clearInterrupted that is
* passed.
*/
@HotSpotIntrinsicCandidate
! private native boolean isInterrupted(boolean clearInterrupted);
/**
* Throws {@link NoSuchMethodError}.
*
* @deprecated This method was originally designed to destroy this
*** 1089,1099 ****
* been started and has not yet died.
*
* @return {@code true} if this thread is alive;
* {@code false} otherwise.
*/
! public final native boolean isAlive();
/**
* Suspends this thread.
* <p>
* First, the {@code checkAccess} method of this thread is called
--- 1173,1191 ----
* been started and has not yet died.
*
* @return {@code true} if this thread is alive;
* {@code false} otherwise.
*/
! public final boolean isAlive() {
! if (this instanceof Fiber) {
! State state = getState();
! return (state != State.NEW && state != State.TERMINATED);
! } else {
! return isAlive0();
! }
! }
! private native boolean isAlive0();
/**
* Suspends this thread.
* <p>
* First, the {@code checkAccess} method of this thread is called
*** 1103,1112 ****
--- 1195,1205 ----
* If the thread is alive, it is suspended and makes no further
* progress unless and until it is resumed.
*
* @throws SecurityException if the current thread cannot modify
* this thread.
+ * @throws UnsupportedOperationException if the current thread is a fiber
* @see #checkAccess
* @deprecated This method has been deprecated, as it is
* inherently deadlock-prone. If the target thread holds a lock on the
* monitor protecting a critical system resource when it is suspended, no
* thread can access this resource until the target thread is resumed. If
*** 1118,1127 ****
--- 1211,1222 ----
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
*/
@Deprecated(since="1.2")
public final void suspend() {
checkAccess();
+ if (this instanceof Fiber)
+ throw new UnsupportedOperationException();
suspend0();
}
/**
* Resumes a suspended thread.
*** 1133,1142 ****
--- 1228,1238 ----
* If the thread is alive but suspended, it is resumed and is
* permitted to make progress in its execution.
*
* @throws SecurityException if the current thread cannot modify this
* thread.
+ * @throws UnsupportedOperationException if the current thread is a fiber
* @see #checkAccess
* @see #suspend()
* @deprecated This method exists solely for use with {@link #suspend},
* which has been deprecated because it is deadlock-prone.
* For more information, see
*** 1144,1153 ****
--- 1240,1251 ----
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
*/
@Deprecated(since="1.2")
public final void resume() {
checkAccess();
+ if (this instanceof Fiber)
+ throw new UnsupportedOperationException();
resume0();
}
/**
* Changes the priority of this thread.
*** 1214,1224 ****
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
! if (threadStatus != 0) {
setNativeName(name);
}
}
/**
--- 1312,1322 ----
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
! if (!(this instanceof Fiber) && threadStatus != 0) {
setNativeName(name);
}
}
/**
*** 1327,1338 ****
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
! public final synchronized void join(long millis)
! throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
--- 1425,1443 ----
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
! public final void join(long millis) throws InterruptedException {
! if (this instanceof Fiber) {
! Fiber f = (Fiber) this;
! long nanos = TimeUnit.NANOSECONDS.convert(millis, TimeUnit.MILLISECONDS);
! f.joinNanos(nanos);
! return;
! }
!
! synchronized (this) {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
*** 1351,1360 ****
--- 1456,1466 ----
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
+ }
/**
* Waits at most {@code millis} milliseconds plus
* {@code nanos} nanoseconds for this thread to die.
*
*** 1377,1389 ****
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
! public final synchronized void join(long millis, int nanos)
! throws InterruptedException {
!
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
--- 1483,1493 ----
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
! public final void join(long millis, int nanos) throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
*** 1426,1436 ****
}
/**
* Marks this thread as either a {@linkplain #isDaemon daemon} thread
* or a user thread. The Java Virtual Machine exits when the only
! * threads running are all daemon threads.
*
* <p> This method must be invoked before the thread is started.
*
* @param on
* if {@code true}, marks this thread as a daemon thread
--- 1530,1542 ----
}
/**
* Marks this thread as either a {@linkplain #isDaemon daemon} thread
* or a user thread. The Java Virtual Machine exits when the only
! * threads running are all daemon threads. The daemon status of {@link
! * Fiber}s is meaningless and does not determine if the Java Virtual Machine
! * exits or not.
*
* <p> This method must be invoked before the thread is started.
*
* @param on
* if {@code true}, marks this thread as a daemon thread
*** 1531,1540 ****
--- 1637,1660 ----
}
return contextClassLoader;
}
/**
+ * TBD
+ */
+ Continuation getContinuation() {
+ return cont;
+ }
+
+ /**
+ * TBD
+ */
+ void setContinuation(Continuation cont) {
+ this.cont = cont;
+ }
+
+ /**
* Sets the context ClassLoader for this Thread. The context
* ClassLoader can be set when a thread is created, and allows
* the creator of the thread to provide the appropriate class loader,
* through {@code getContextClassLoader}, to code running in the thread
* when loading classes and resources.
*** 2012,2035 ****
--- 2132,2159 ----
}
/**
* Set the handler invoked when this thread abruptly terminates
* due to an uncaught exception.
+ *
* <p>A thread can take full control of how it responds to uncaught
* exceptions by having its uncaught exception handler explicitly set.
* If no such handler is set then the thread's {@code ThreadGroup}
* object acts as its handler.
* @param eh the object to use as this thread's uncaught exception
* handler. If {@code null} then this thread has no explicit handler.
+ * @throws UnsupportedOperationException if the thread is a fiber
* @throws SecurityException if the current thread is not allowed to
* modify this thread.
* @see #setDefaultUncaughtExceptionHandler
* @see ThreadGroup#uncaughtException
* @since 1.5
*/
public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
checkAccess();
+ if (this instanceof Fiber)
+ throw new UnsupportedOperationException();
uncaughtExceptionHandler = eh;
}
/**
* Dispatch an uncaught exception to the handler. This method is
*** 2106,2125 ****
// managed by class java.util.concurrent.ThreadLocalRandom. These
// fields are used to build the high-performance PRNGs in the
// concurrent code, and we can not risk accidental false sharing.
// Hence, the fields are isolated with @Contended.
/** The current seed for a ThreadLocalRandom */
! @jdk.internal.vm.annotation.Contended("tlr")
long threadLocalRandomSeed;
/** Probe hash value; nonzero if threadLocalRandomSeed initialized */
! @jdk.internal.vm.annotation.Contended("tlr")
int threadLocalRandomProbe;
/** Secondary seed isolated from public ThreadLocalRandom sequence */
! @jdk.internal.vm.annotation.Contended("tlr")
int threadLocalRandomSecondarySeed;
/* Some private helper methods */
private native void setPriority0(int newPriority);
private native void stop0(Object o);
--- 2230,2251 ----
// managed by class java.util.concurrent.ThreadLocalRandom. These
// fields are used to build the high-performance PRNGs in the
// concurrent code, and we can not risk accidental false sharing.
// Hence, the fields are isolated with @Contended.
+ // FIXME: can we move these to a helper object?
+
/** The current seed for a ThreadLocalRandom */
! //@jdk.internal.vm.annotation.Contended("tlr")
long threadLocalRandomSeed;
/** Probe hash value; nonzero if threadLocalRandomSeed initialized */
! //@jdk.internal.vm.annotation.Contended("tlr")
int threadLocalRandomProbe;
/** Secondary seed isolated from public ThreadLocalRandom sequence */
! //@jdk.internal.vm.annotation.Contended("tlr")
int threadLocalRandomSecondarySeed;
/* Some private helper methods */
private native void setPriority0(int newPriority);
private native void stop0(Object o);
< prev index next >