diff options
author | jfrijters <jfrijters> | 2014-11-10 12:18:25 +0300 |
---|---|---|
committer | jfrijters <jfrijters> | 2014-11-10 12:18:25 +0300 |
commit | b46dcf01d7586e0d28892cb8a5c7ad8366cd39b7 (patch) | |
tree | ea88c2a4acc99d22edbe7c7b84d7f2781ec80e34 /openjdk/java | |
parent | 2092fc1da560398f9174a667dbc3569f2476a6cd (diff) |
Changed Thread.parkBlocker field accessiblity to internal, to allow java.util.concurrent.ForkJoinPool direct access.
Diffstat (limited to 'openjdk/java')
-rw-r--r-- | openjdk/java/lang/Thread.java | 3 | ||||
-rw-r--r-- | openjdk/java/util/concurrent/locks/LockSupport.java | 56 |
2 files changed, 43 insertions, 16 deletions
diff --git a/openjdk/java/lang/Thread.java b/openjdk/java/lang/Thread.java index e61147e3..0ed60578 100644 --- a/openjdk/java/lang/Thread.java +++ b/openjdk/java/lang/Thread.java @@ -256,7 +256,8 @@ class Thread implements Runnable { * Set by (private) java.util.concurrent.locks.LockSupport.setBlocker * Accessed using java.util.concurrent.locks.LockSupport.getBlocker */ - volatile Object parkBlocker; + @ikvm.lang.Internal // [IKVM] accessed from java.util.concurrent + public volatile Object parkBlocker; /* The object in which this thread is blocked in an interruptible I/O * operation, if any. The blocker's interrupt method should be invoked diff --git a/openjdk/java/util/concurrent/locks/LockSupport.java b/openjdk/java/util/concurrent/locks/LockSupport.java index 1bcec807..14112c3f 100644 --- a/openjdk/java/util/concurrent/locks/LockSupport.java +++ b/openjdk/java/util/concurrent/locks/LockSupport.java @@ -34,8 +34,6 @@ */ package java.util.concurrent.locks; -import java.util.concurrent.*; - /** * Basic thread blocking primitives for creating locks and other @@ -68,16 +66,19 @@ import java.util.concurrent.*; * {@code blocker} object parameter. This object is recorded while * the thread is blocked to permit monitoring and diagnostic tools to * identify the reasons that threads are blocked. (Such tools may - * access blockers using method {@link #getBlocker}.) The use of these - * forms rather than the original forms without this parameter is - * strongly encouraged. The normal argument to supply as a - * {@code blocker} within a lock implementation is {@code this}. + * access blockers using method {@link #getBlocker(Thread)}.) + * The use of these forms rather than the original forms without this + * parameter is strongly encouraged. The normal argument to supply as + * a {@code blocker} within a lock implementation is {@code this}. * * <p>These methods are designed to be used as tools for creating * higher-level synchronization utilities, and are not in themselves * useful for most concurrency control applications. The {@code park} * method is designed for use only in constructions of the form: - * <pre>while (!canProceed()) { ... LockSupport.park(this); }</pre> + * + * <pre> {@code + * while (!canProceed()) { ... LockSupport.park(this); }}</pre> + * * where neither {@code canProceed} nor any other actions prior to the * call to {@code park} entail locking or blocking. Because only one * permit is associated with each thread, any intermediary uses of @@ -85,7 +86,7 @@ import java.util.concurrent.*; * * <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out * non-reentrant lock class: - * <pre>{@code + * <pre> {@code * class FIFOMutex { * private final AtomicBoolean locked = new AtomicBoolean(false); * private final Queue<Thread> waiters @@ -99,14 +100,14 @@ import java.util.concurrent.*; * // Block while not first in queue or cannot acquire lock * while (waiters.peek() != current || * !locked.compareAndSet(false, true)) { - * LockSupport.park(this); - * if (Thread.interrupted()) // ignore interrupts while waiting - * wasInterrupted = true; + * LockSupport.park(this); + * if (Thread.interrupted()) // ignore interrupts while waiting + * wasInterrupted = true; * } * * waiters.remove(); * if (wasInterrupted) // reassert interrupt status on exit - * current.interrupt(); + * current.interrupt(); * } * * public void unlock() { @@ -115,16 +116,18 @@ import java.util.concurrent.*; * } * }}</pre> */ - public class LockSupport { private LockSupport() {} // Cannot be instantiated. + private static void setBlocker(Thread t, Object arg) { + t.parkBlocker = arg; + } + private static final int PARK_STATE_RUNNING = 0; private static final int PARK_STATE_PERMIT = 1; private static final int PARK_STATE_PARKED = 2; // these native methods are all implemented in map.xml - private static native void setBlocker(Thread t, Object obj); private static native int cmpxchgParkState(Thread t, int newValue, int comparand); private static native Object getParkLock(Thread t); private static native void setParkLock(Thread t, Object obj); @@ -329,7 +332,11 @@ public class LockSupport { * @throws NullPointerException if argument is null * @since 1.6 */ - public static native Object getBlocker(Thread t); // implemented in map.xml + public static Object getBlocker(Thread t) { + if (t == null) + throw new NullPointerException(); + return t.parkBlocker; + } /** * Disables the current thread for thread scheduling purposes unless the @@ -427,4 +434,23 @@ public class LockSupport { public static void parkUntil(long deadline) { parkImpl(Thread.currentThread(), 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 = t.threadLocalRandomSecondarySeed) != 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 + t.threadLocalRandomSecondarySeed = r; + return r; + } + } |