< prev index next >

src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java

Print this page

        

*** 33,42 **** --- 33,45 ---- * http://creativecommons.org/publicdomain/zero/1.0/ */ package java.util.concurrent.locks; + import java.util.concurrent.TimeUnit; + + import jdk.internal.misc.Strands; import jdk.internal.misc.Unsafe; /** * Basic thread blocking primitives for creating locks and other * synchronization classes.
*** 139,149 **** public class LockSupport { private LockSupport() {} // Cannot be instantiated. private static void setBlocker(Thread t, Object arg) { // Even though volatile, hotspot doesn't need a write barrier here. ! U.putReference(t, PARKBLOCKER, arg); } /** * Makes available the permit for the given thread, if it * was not already available. If the thread was blocked on --- 142,157 ---- public class LockSupport { private LockSupport() {} // Cannot be instantiated. private static void setBlocker(Thread t, Object arg) { // Even though volatile, hotspot doesn't need a write barrier here. ! U.putReference(t, THREAD_PARKBLOCKER, arg); ! } ! ! private static void setBlocker(Fiber<?> f, Object arg) { ! // Even though volatile, hotspot doesn't need a write barrier here. ! U.putReference(f, FIBER_PARKBLOCKER, arg); } /** * Makes available the permit for the given thread, if it * was not already available. If the thread was blocked on
*** 154,165 **** * * @param thread the thread to unpark, or {@code null}, in which case * this operation has no effect */ public static void unpark(Thread thread) { ! if (thread != null) ! U.unpark(thread); } /** * Disables the current thread for thread scheduling purposes unless the * permit is available. --- 162,204 ---- * * @param thread the thread to unpark, or {@code null}, in which case * this operation has no effect */ public static void unpark(Thread thread) { ! if (thread != null) { ! Fiber<?> fiber = Strands.getFiber(thread); ! if (fiber != null) { ! Strands.unparkFiber(fiber); // can throw RejectedExecutionException ! } else { ! U.unpark(thread); ! } ! } ! } ! ! /** ! * Makes available the permit for the given strand, if it ! * was not already available. If the strand was blocked on ! * {@code park} then it will unblock. Otherwise, its next call ! * to {@code park} is guaranteed not to block. This operation ! * is not guaranteed to have any effect at all if the given ! * strand is a Thread that has not been started. ! * ! * @param strand the strand to unpark, or {@code null}, in which case ! * this operation has no effect ! * @throws IllegalArgumentException if strand is not a {@code Thread}, ! * {@code Fiber} or {@code null} ! */ ! public static void unpark(Object strand) { ! if (strand != null) { ! if (strand instanceof Thread) { ! unpark((Thread) strand); ! } else if (strand instanceof Fiber) { ! Strands.unparkFiber((Fiber<?>) strand); // can throw RejectedExecutionException ! } else { ! throw new IllegalArgumentException(); ! } ! } } /** * Disables the current thread for thread scheduling purposes unless the * permit is available.
*** 187,200 **** * @param blocker the synchronization object responsible for this * thread parking * @since 1.6 */ public static void park(Object blocker) { ! Thread t = Thread.currentThread(); ! setBlocker(t, blocker); ! U.park(false, 0L); ! setBlocker(t, null); } /** * Disables the current thread for thread scheduling purposes, for up to * the specified waiting time, unless the permit is available. --- 226,247 ---- * @param blocker the synchronization object responsible for this * thread parking * @since 1.6 */ public static void park(Object blocker) { ! Object strand = Strands.currentStrand(); ! if (strand instanceof Fiber) { ! Fiber<?> fiber = (Fiber<?>) strand; ! setBlocker(fiber, blocker); ! Strands.parkFiber(); ! setBlocker(fiber, null); ! } else { ! Thread thread = (Thread) strand; ! setBlocker(thread, blocker); ! U.park(false, 0L); ! setBlocker(thread, null); ! } } /** * Disables the current thread for thread scheduling purposes, for up to * the specified waiting time, unless the permit is available.
*** 228,241 **** * @param nanos the maximum number of nanoseconds to wait * @since 1.6 */ public static void parkNanos(Object blocker, long nanos) { if (nanos > 0) { ! Thread t = Thread.currentThread(); ! setBlocker(t, blocker); ! U.park(false, nanos); ! setBlocker(t, null); } } /** * Disables the current thread for thread scheduling purposes, until --- 275,296 ---- * @param nanos the maximum number of nanoseconds to wait * @since 1.6 */ public static void parkNanos(Object blocker, long nanos) { if (nanos > 0) { ! Object strand = Strands.currentStrand(); ! if (strand instanceof Fiber) { ! Fiber<?> fiber = (Fiber<?>) strand; ! setBlocker(fiber, blocker); ! Strands.parkFiber(nanos); ! setBlocker(fiber, null); ! } else { ! Thread thread = (Thread) strand; ! setBlocker(thread, blocker); ! U.park(false, nanos); ! setBlocker(thread, null); ! } } } /** * Disables the current thread for thread scheduling purposes, until
*** 269,282 **** * @param deadline the absolute time, in milliseconds from the Epoch, * to wait until * @since 1.6 */ public static void parkUntil(Object blocker, long deadline) { ! Thread t = Thread.currentThread(); ! setBlocker(t, blocker); ! U.park(true, deadline); ! setBlocker(t, null); } /** * Returns the blocker object supplied to the most recent * invocation of a park method that has not yet unblocked, or null --- 324,347 ---- * @param deadline the absolute time, in milliseconds from the Epoch, * to wait until * @since 1.6 */ public static void parkUntil(Object blocker, long deadline) { ! Object strand = Strands.currentStrand(); ! if (strand instanceof Fiber) { ! Fiber<?> fiber = (Fiber<?>) strand; ! setBlocker(fiber, blocker); ! long millis = deadline - System.currentTimeMillis(); ! long nanos = TimeUnit.NANOSECONDS.convert(millis, TimeUnit.MILLISECONDS); ! Strands.parkFiber(nanos); ! setBlocker(fiber, null); ! } else { ! Thread thread = (Thread) strand; ! setBlocker(thread, blocker); ! U.park(true, deadline); ! setBlocker(thread, null); ! } } /** * Returns the blocker object supplied to the most recent * invocation of a park method that has not yet unblocked, or null
*** 290,300 **** * @since 1.6 */ public static Object getBlocker(Thread t) { if (t == null) throw new NullPointerException(); ! return U.getReferenceVolatile(t, PARKBLOCKER); } /** * Disables the current thread for thread scheduling purposes unless the * permit is available. --- 355,365 ---- * @since 1.6 */ public static Object getBlocker(Thread t) { if (t == null) throw new NullPointerException(); ! return U.getReferenceVolatile(t, THREAD_PARKBLOCKER); } /** * Disables the current thread for thread scheduling purposes unless the * permit is available.
*** 319,329 **** * method to return. Callers should re-check the conditions which caused * the thread to park in the first place. Callers may also determine, * for example, the interrupt status of the thread upon return. */ public static void park() { ! U.park(false, 0L); } /** * Disables the current thread for thread scheduling purposes, for up to * the specified waiting time, unless the permit is available. --- 384,399 ---- * method to return. Callers should re-check the conditions which caused * the thread to park in the first place. Callers may also determine, * for example, the interrupt status of the thread upon return. */ public static void park() { ! Object strand = Strands.currentStrand(); ! if (strand instanceof Fiber) { ! Strands.parkFiber(); ! } else { ! U.park(false, 0L); ! } } /** * Disables the current thread for thread scheduling purposes, for up to * the specified waiting time, unless the permit is available.
*** 353,364 **** * upon return. * * @param nanos the maximum number of nanoseconds to wait */ public static void parkNanos(long nanos) { ! if (nanos > 0) ! U.park(false, nanos); } /** * Disables the current thread for thread scheduling purposes, until * the specified deadline, unless the permit is available. --- 423,440 ---- * upon return. * * @param nanos the maximum number of nanoseconds to wait */ public static void parkNanos(long nanos) { ! if (nanos > 0) { ! Object strand = Strands.currentStrand(); ! if (strand instanceof Fiber) { ! Strands.parkFiber(nanos); ! } else { ! U.park(false, nanos); ! } ! } } /** * Disables the current thread for thread scheduling purposes, until * the specified deadline, unless the permit is available.
*** 388,398 **** * * @param deadline the absolute time, in milliseconds from the Epoch, * to wait until */ public static void parkUntil(long deadline) { ! U.park(true, deadline); } /** * Returns the pseudo-randomly initialized or updated secondary seed. * Copied from ThreadLocalRandom due to package access restrictions. --- 464,481 ---- * * @param deadline the absolute time, in milliseconds from the Epoch, * to wait until */ public static void parkUntil(long deadline) { ! Object strand = Strands.currentStrand(); ! if (strand instanceof Fiber) { ! long millis = deadline - System.currentTimeMillis(); ! long nanos = TimeUnit.NANOSECONDS.convert(millis, TimeUnit.MILLISECONDS); ! Strands.parkFiber(nanos); ! } else { ! U.park(true, deadline); ! } } /** * Returns the pseudo-randomly initialized or updated secondary seed. * Copied from ThreadLocalRandom due to package access restrictions.
*** 421,432 **** return U.getLong(thread, TID); } // Hotspot implementation via intrinsics API private static final Unsafe U = Unsafe.getUnsafe(); ! private static final long PARKBLOCKER = U.objectFieldOffset (Thread.class, "parkBlocker"); private static final long SECONDARY = U.objectFieldOffset (Thread.class, "threadLocalRandomSecondarySeed"); private static final long TID = U.objectFieldOffset (Thread.class, "tid"); --- 504,517 ---- return U.getLong(thread, TID); } // Hotspot implementation via intrinsics API private static final Unsafe U = Unsafe.getUnsafe(); ! private static final long THREAD_PARKBLOCKER = U.objectFieldOffset (Thread.class, "parkBlocker"); + private static final long FIBER_PARKBLOCKER = U.objectFieldOffset + (Fiber.class, "parkBlocker"); private static final long SECONDARY = U.objectFieldOffset (Thread.class, "threadLocalRandomSecondarySeed"); private static final long TID = U.objectFieldOffset (Thread.class, "tid");
< prev index next >