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

Print this page

        

*** 118,141 **** * }}</pre> */ public class LockSupport { private LockSupport() {} // Cannot be instantiated. - // Hotspot implementation via intrinsics API - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long parkBlockerOffset; - - static { - try { - parkBlockerOffset = unsafe.objectFieldOffset - (java.lang.Thread.class.getDeclaredField("parkBlocker")); - } catch (Exception ex) { throw new Error(ex); } - } - private static void setBlocker(Thread t, Object arg) { // Even though volatile, hotspot doesn't need a write barrier here. ! unsafe.putObject(t, parkBlockerOffset, arg); } /** * Makes available the permit for the given thread, if it * was not already available. If the thread was blocked on --- 118,130 ---- * }}</pre> */ 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. ! UNSAFE.putObject(t, parkBlockerOffset, arg); } /** * Makes available the permit for the given thread, if it * was not already available. If the thread was blocked on
*** 147,157 **** * @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) ! unsafe.unpark(thread); } /** * Disables the current thread for thread scheduling purposes unless the * permit is available. --- 136,146 ---- * @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) ! UNSAFE.unpark(thread); } /** * Disables the current thread for thread scheduling purposes unless the * permit is available.
*** 181,191 **** * @since 1.6 */ public static void park(Object blocker) { Thread t = Thread.currentThread(); setBlocker(t, blocker); ! unsafe.park(false, 0L); setBlocker(t, null); } /** * Disables the current thread for thread scheduling purposes, for up to --- 170,180 ---- * @since 1.6 */ public static void park(Object blocker) { Thread t = Thread.currentThread(); setBlocker(t, blocker); ! UNSAFE.park(false, 0L); setBlocker(t, null); } /** * Disables the current thread for thread scheduling purposes, for up to
*** 221,231 **** */ public static void parkNanos(Object blocker, long nanos) { if (nanos > 0) { Thread t = Thread.currentThread(); setBlocker(t, blocker); ! unsafe.park(false, nanos); setBlocker(t, null); } } /** --- 210,220 ---- */ public static void parkNanos(Object blocker, long nanos) { if (nanos > 0) { Thread t = Thread.currentThread(); setBlocker(t, blocker); ! UNSAFE.park(false, nanos); setBlocker(t, null); } } /**
*** 262,272 **** * @since 1.6 */ public static void parkUntil(Object blocker, long deadline) { Thread t = Thread.currentThread(); setBlocker(t, blocker); ! unsafe.park(true, deadline); setBlocker(t, null); } /** * Returns the blocker object supplied to the most recent --- 251,261 ---- * @since 1.6 */ public static void parkUntil(Object blocker, long deadline) { Thread t = Thread.currentThread(); setBlocker(t, blocker); ! UNSAFE.park(true, deadline); setBlocker(t, null); } /** * Returns the blocker object supplied to the most recent
*** 281,291 **** * @since 1.6 */ public static Object getBlocker(Thread t) { if (t == null) throw new NullPointerException(); ! return unsafe.getObjectVolatile(t, parkBlockerOffset); } /** * Disables the current thread for thread scheduling purposes unless the * permit is available. --- 270,280 ---- * @since 1.6 */ public static Object getBlocker(Thread t) { if (t == null) throw new NullPointerException(); ! return UNSAFE.getObjectVolatile(t, parkBlockerOffset); } /** * Disables the current thread for thread scheduling purposes unless the * permit is available.
*** 310,320 **** * 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() { ! unsafe.park(false, 0L); } /** * Disables the current thread for thread scheduling purposes, for up to * the specified waiting time, unless the permit is available. --- 299,309 ---- * 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() { ! UNSAFE.park(false, 0L); } /** * Disables the current thread for thread scheduling purposes, for up to * the specified waiting time, unless the permit is available.
*** 344,354 **** * * @param nanos the maximum number of nanoseconds to wait */ public static void parkNanos(long nanos) { if (nanos > 0) ! unsafe.park(false, nanos); } /** * Disables the current thread for thread scheduling purposes, until * the specified deadline, unless the permit is available. --- 333,343 ---- * * @param nanos the maximum number of nanoseconds to wait */ public static void parkNanos(long nanos) { if (nanos > 0) ! UNSAFE.park(false, nanos); } /** * Disables the current thread for thread scheduling purposes, until * the specified deadline, unless the permit is available.
*** 378,385 **** * * @param deadline the absolute time, in milliseconds from the Epoch, * to wait until */ public static void parkUntil(long deadline) { ! unsafe.park(true, deadline); } } --- 367,414 ---- * * @param deadline the absolute time, in milliseconds from the Epoch, * to wait until */ public static void parkUntil(long deadline) { ! UNSAFE.park(true, deadline); } + + /** + * Returns the pseudo-randomly initialized or updated secondary seed. + * Copied from ThreadLocalRandom due to package access restrictions + */ + static final int nextSecondarySeed() { + int r; + Thread t = Thread.currentThread(); + if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) { + r ^= r << 13; // xorshift + r ^= r >>> 17; + r ^= r << 5; + } + else if ((r = java.util.concurrent.ThreadLocalRandom.current().nextInt()) == 0) + r = 1; // avoid zero + UNSAFE.putInt(t, SECONDARY, r); + return r; + } + + // Hotspot implementation via intrinsics API + private static final sun.misc.Unsafe UNSAFE; + private static final long parkBlockerOffset; + private static final long SEED; + private static final long PROBE; + private static final long SECONDARY; + static { + try { + UNSAFE = sun.misc.Unsafe.getUnsafe(); + Class<?> tk = Thread.class; + parkBlockerOffset = UNSAFE.objectFieldOffset + (tk.getDeclaredField("parkBlocker")); + SEED = UNSAFE.objectFieldOffset + (tk.getDeclaredField("threadLocalRandomSeed")); + PROBE = UNSAFE.objectFieldOffset + (tk.getDeclaredField("threadLocalRandomProbe")); + SECONDARY = UNSAFE.objectFieldOffset + (tk.getDeclaredField("threadLocalRandomSecondarySeed")); + } catch (Exception ex) { throw new Error(ex); } + } + }