From eb6ab98ebcbf837b1ed052b46b1c022a3d79e34e Mon Sep 17 00:00:00 2001
From: Doug Lea
Date: Tue, 16 Feb 2016 09:52:49 -0800
Subject: [PATCH] 8145485: Miscellaneous changes imported from jsr166 CVS
2016-02
Reviewed-by: martin, psandoz, chegar
---
.../classes/java/util/SplittableRandom.java | 11 +++--
.../java/util/concurrent/Exchanger.java | 7 ++--
.../java/util/concurrent/ForkJoinPool.java | 5 ++-
.../java/util/concurrent/ForkJoinTask.java | 40 ++++++++-----------
.../util/concurrent/ThreadLocalRandom.java | 11 +++--
.../util/concurrent/atomic/Striped64.java | 14 +++----
.../ConcurrentQueues/RemovePollRace.java | 12 ++++--
.../ExecutorCompletionServiceLoops.java | 4 +-
8 files changed, 50 insertions(+), 54 deletions(-)
diff --git a/jdk/src/java.base/share/classes/java/util/SplittableRandom.java b/jdk/src/java.base/share/classes/java/util/SplittableRandom.java
index 2e08a4ddb87..cf71c91e8da 100644
--- a/jdk/src/java.base/share/classes/java/util/SplittableRandom.java
+++ b/jdk/src/java.base/share/classes/java/util/SplittableRandom.java
@@ -225,14 +225,13 @@ public final class SplittableRandom {
private static final AtomicLong defaultGen = new AtomicLong(initialSeed());
private static long initialSeed() {
- String pp = java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction(
- "java.util.secureRandomSeed"));
- if (pp != null && pp.equalsIgnoreCase("true")) {
+ java.security.PrivilegedAction action =
+ () -> Boolean.getBoolean("java.util.secureRandomSeed");
+ if (java.security.AccessController.doPrivileged(action)) {
byte[] seedBytes = java.security.SecureRandom.getSeed(8);
- long s = (long)(seedBytes[0]) & 0xffL;
+ long s = (long)seedBytes[0] & 0xffL;
for (int i = 1; i < 8; ++i)
- s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
+ s = (s << 8) | ((long)seedBytes[i] & 0xffL);
return s;
}
return (mix64(System.currentTimeMillis()) ^
diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java b/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java
index b8260d7102b..3f5ce5e371d 100644
--- a/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java
@@ -155,8 +155,8 @@ public class Exchanger {
* a value that is enough for common platforms. Additionally,
* extra care elsewhere is taken to avoid other false/unintended
* sharing and to enhance locality, including adding padding (via
- * jdk.internal.vm.annotation.Contended) to Nodes, embedding "bound" as an Exchanger
- * field, and reworking some park/unpark mechanics compared to
+ * @Contended) to Nodes, embedding "bound" as an Exchanger field,
+ * and reworking some park/unpark mechanics compared to
* LockSupport versions.
*
* The arena starts out with only one used slot. We expand the
@@ -304,8 +304,7 @@ public class Exchanger {
/**
* Nodes hold partially exchanged data, plus other per-thread
- * bookkeeping. Padded via @jdk.internal.vm.annotation.Contended to reduce memory
- * contention.
+ * bookkeeping. Padded via @Contended to reduce memory contention.
*/
@jdk.internal.vm.annotation.Contended static final class Node {
int index; // Arena index
diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java
index 3dac70a4310..3a7c0ab4eb8 100644
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java
@@ -818,8 +818,9 @@ public class ForkJoinPool extends AbstractExecutorService {
final ForkJoinPool pool; // the containing pool (may be null)
final ForkJoinWorkerThread owner; // owning thread or null if shared
volatile Thread parker; // == owner during call to park; else null
- volatile ForkJoinTask> currentJoin; // task being joined in awaitJoin
- @jdk.internal.vm.annotation.Contended("group2") // separate from other fields
+ volatile ForkJoinTask> currentJoin; // task being joined in awaitJoin
+
+ @jdk.internal.vm.annotation.Contended("group2") // segregate
volatile ForkJoinTask> currentSteal; // nonnull when running some task
WorkQueue(ForkJoinPool pool, ForkJoinWorkerThread owner) {
diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java
index 888794e8e40..fa14cbf984a 100644
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java
@@ -541,16 +541,16 @@ public abstract class ForkJoinTask implements Future, Serializable {
}
/**
- * Returns a rethrowable exception for the given task, if
- * available. To provide accurate stack traces, if the exception
- * was not thrown by the current thread, we try to create a new
- * exception of the same type as the one thrown, but with the
- * recorded exception as its cause. If there is no such
- * constructor, we instead try to use a no-arg constructor,
- * followed by initCause, to the same effect. If none of these
- * apply, or any fail due to other exceptions, we return the
- * recorded exception, which is still correct, although it may
- * contain a misleading stack trace.
+ * Returns a rethrowable exception for this task, if available.
+ * To provide accurate stack traces, if the exception was not
+ * thrown by the current thread, we try to create a new exception
+ * of the same type as the one thrown, but with the recorded
+ * exception as its cause. If there is no such constructor, we
+ * instead try to use a no-arg constructor, followed by initCause,
+ * to the same effect. If none of these apply, or any fail due to
+ * other exceptions, we return the recorded exception, which is
+ * still correct, although it may contain a misleading stack
+ * trace.
*
* @return the exception, or null if none
*/
@@ -572,26 +572,20 @@ public abstract class ForkJoinTask implements Future, Serializable {
if (e == null || (ex = e.ex) == null)
return null;
if (e.thrower != Thread.currentThread().getId()) {
- Class extends Throwable> ec = ex.getClass();
try {
Constructor> noArgCtor = null;
- Constructor>[] cs = ec.getConstructors();// public ctors only
- for (int i = 0; i < cs.length; ++i) {
- Constructor> c = cs[i];
+ // public ctors only
+ for (Constructor> c : ex.getClass().getConstructors()) {
Class>[] ps = c.getParameterTypes();
if (ps.length == 0)
noArgCtor = c;
- else if (ps.length == 1 && ps[0] == Throwable.class) {
- Throwable wx = (Throwable)c.newInstance(ex);
- return (wx == null) ? ex : wx;
- }
+ else if (ps.length == 1 && ps[0] == Throwable.class)
+ return (Throwable)c.newInstance(ex);
}
if (noArgCtor != null) {
- Throwable wx = (Throwable)(noArgCtor.newInstance());
- if (wx != null) {
- wx.initCause(ex);
- return wx;
- }
+ Throwable wx = (Throwable)noArgCtor.newInstance();
+ wx.initCause(ex);
+ return wx;
}
} catch (Exception ignore) {
}
diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java
index f4bf5a4fef2..90fb6cf054f 100644
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java
@@ -134,14 +134,13 @@ public class ThreadLocalRandom extends Random {
private static final AtomicLong seeder = new AtomicLong(initialSeed());
private static long initialSeed() {
- String pp = java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction(
- "java.util.secureRandomSeed"));
- if (pp != null && pp.equalsIgnoreCase("true")) {
+ java.security.PrivilegedAction action =
+ () -> Boolean.getBoolean("java.util.secureRandomSeed");
+ if (java.security.AccessController.doPrivileged(action)) {
byte[] seedBytes = java.security.SecureRandom.getSeed(8);
- long s = (long)(seedBytes[0]) & 0xffL;
+ long s = (long)seedBytes[0] & 0xffL;
for (int i = 1; i < 8; ++i)
- s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
+ s = (s << 8) | ((long)seedBytes[i] & 0xffL);
return s;
}
return (mix64(System.currentTimeMillis()) ^
diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java
index dad7db6bd77..77ee89a614b 100644
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java
@@ -55,13 +55,13 @@ abstract class Striped64 extends Number {
* accessed directly by subclasses.
*
* Table entries are of class Cell; a variant of AtomicLong padded
- * (via @jdk.internal.vm.annotation.Contended) to reduce cache contention. Padding
- * is overkill for most Atomics because they are usually
- * irregularly scattered in memory and thus don't interfere much
- * with each other. But Atomic objects residing in arrays will
- * tend to be placed adjacent to each other, and so will most
- * often share cache lines (with a huge negative performance
- * impact) without this precaution.
+ * (via @Contended) to reduce cache contention. Padding is
+ * overkill for most Atomics because they are usually irregularly
+ * scattered in memory and thus don't interfere much with each
+ * other. But Atomic objects residing in arrays will tend to be
+ * placed adjacent to each other, and so will most often share
+ * cache lines (with a huge negative performance impact) without
+ * this precaution.
*
* In part because Cells are relatively large, we avoid creating
* them until they are needed. When there is no contention, all
diff --git a/jdk/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java b/jdk/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java
index 4fe26337092..abcae1d398a 100644
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java
@@ -121,12 +121,16 @@ public class RemovePollRace {
final int SPINS = 5;
final AtomicLong removes = new AtomicLong(0);
final AtomicLong polls = new AtomicLong(0);
- final int adderCount =
- Math.max(1, Runtime.getRuntime().availableProcessors() / 4);
- final int removerCount =
- Math.max(1, Runtime.getRuntime().availableProcessors() / 4);
+
+ // We need at least 3 threads, but we don't want to use too
+ // many on massively multi-core systems.
+ final int cpus = Runtime.getRuntime().availableProcessors();
+ final int threadsToUse = Math.max(3, Math.min(cpus, 16));
+ final int adderCount = threadsToUse / 3;
+ final int removerCount = adderCount;
final int pollerCount = removerCount;
final int threadCount = adderCount + removerCount + pollerCount;
+
final CountDownLatch startingGate = new CountDownLatch(1);
final CountDownLatch addersDone = new CountDownLatch(adderCount);
final Runnable remover = new Runnable() {
diff --git a/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java b/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java
index e5afd0a4dfc..1da7f2335c7 100644
--- a/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java
+++ b/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java
@@ -61,13 +61,13 @@ public class ExecutorCompletionServiceLoops {
max = Integer.parseInt(args[0]);
System.out.println("Warmup...");
- oneTest( base );
+ oneTest(base);
Thread.sleep(100);
print = true;
for (int i = 1; i <= max; i += (i+1) >>> 1) {
System.out.print("n: " + i * base);
- oneTest(i * base );
+ oneTest(i * base);
Thread.sleep(100);
}
pool.shutdown();