From 9d83225bdcd50d82d9e20c83cdf1acda334db3a0 Mon Sep 17 00:00:00 2001 From: shade Date: Fri, 5 Jul 2019 16:22:19 +0200 Subject: [PATCH] 8227018: CompletableFuture should not call Runtime.availableProcessors on fast path Reviewed-by: dl, martin --- .../java/util/concurrent/CompletableFuture.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/share/classes/java/util/concurrent/CompletableFuture.java b/src/share/classes/java/util/concurrent/CompletableFuture.java index 955daabed..d645bb4c3 100644 --- a/src/share/classes/java/util/concurrent/CompletableFuture.java +++ b/src/share/classes/java/util/concurrent/CompletableFuture.java @@ -421,6 +421,20 @@ public class CompletableFuture implements Future, CompletionStage { static final int ASYNC = 1; static final int NESTED = -1; + /** + * Spins before blocking in waitingGet. + * There is no need to spin on uniprocessors. + * + * Call to Runtime.availableProcessors is expensive, cache the value here. + * This unfortunately relies on the number of available CPUs during first + * initialization. This affects the case when MP system would report only + * one CPU available at startup, initialize SPINS to 0, and then make more + * CPUs online. This would incur some performance penalty due to less spins + * than would otherwise happen. + */ + private static final int SPINS = (Runtime.getRuntime().availableProcessors() > 1 ? + 1 << 8 : 0); + /* ------------- Base Completion classes and operations -------------- */ @SuppressWarnings("serial") @@ -1709,8 +1723,7 @@ public class CompletableFuture implements Future, CompletionStage { Object r; while ((r = result) == null) { if (spins < 0) - spins = (Runtime.getRuntime().availableProcessors() > 1) ? - 1 << 8 : 0; // Use brief spin-wait on multiprocessors + spins = SPINS; else if (spins > 0) { if (ThreadLocalRandom.nextSecondarySeed() >= 0) --spins; -- GitLab