< 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 >