diff --git a/substratevm/CHANGELOG.md b/substratevm/CHANGELOG.md index 7cd24cfb122f..6fcfce6e8539 100644 --- a/substratevm/CHANGELOG.md +++ b/substratevm/CHANGELOG.md @@ -13,6 +13,7 @@ At runtime, premain runtime options are set along with main class' arguments in * (GR-58000) Support for `GetStringUTFLengthAsLong` added in JNI_VERSION_24 ([JDK-8328877](https://bugs.openjdk.org/browse/JDK-8328877)) * (GR-58383) The length of the printed stack trace when using `-XX:MissingRegistrationReportingMode=Warn` can now be set with `-XX:MissingRegistrationWarnContextLines=` and its default length is now 8. * (GR-58914) `ActiveProcessorCount` must be set at isolate or VM creation time. +* (GR-59326) Ensure builder ForkJoin commonPool parallelism always respects NativeImageOptions.NumberOfThreads. ## GraalVM for JDK 23 (Internal Version 24.1.0) * (GR-51520) The old class initialization strategy, which was deprecated in GraalVM for JDK 22, is removed. The option `StrictImageHeap` no longer has any effect. diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageOptions.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageOptions.java index 1d3446610fcd..fe3cb0f92f23 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageOptions.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageOptions.java @@ -38,9 +38,9 @@ import com.oracle.graal.pointsto.reports.ReportUtils; import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.option.APIOption; +import com.oracle.svm.core.option.AccumulatingLocatableMultiOptionValue; import com.oracle.svm.core.option.BundleMember; import com.oracle.svm.core.option.HostedOptionKey; -import com.oracle.svm.core.option.AccumulatingLocatableMultiOptionValue; import com.oracle.svm.core.option.SubstrateOptionsParser; import com.oracle.svm.core.util.InterruptImageBuilding; import com.oracle.svm.core.util.UserError; @@ -214,28 +214,26 @@ public static int getActualNumberOfThreads() { } public static void setCommonPoolParallelism(OptionValues optionValues) { - if (NativeImageOptions.NumberOfThreads.hasBeenSet(optionValues)) { - /* - * The main thread always helps to process tasks submitted to the common pool (e.g., see - * ForkJoinPool#awaitTermination()), so subtract one from the number of threads. The - * common pool can be disabled "by setting the parallelism property to zero" (see - * ForkJoinPool's javadoc). - */ - int numberOfCommonPoolThreads = NativeImageOptions.NumberOfThreads.getValue(optionValues) - 1; - String commonPoolParallelismProperty = "java.util.concurrent.ForkJoinPool.common.parallelism"; - assert System.getProperty(commonPoolParallelismProperty) == null : commonPoolParallelismProperty + " already set"; - System.setProperty(commonPoolParallelismProperty, "" + numberOfCommonPoolThreads); - int actualCommonPoolParallelism = ForkJoinPool.commonPool().getParallelism(); - /* - * getParallelism() returns at least 1, even in single-threaded mode where common pool - * is disabled. - */ - boolean isSingleThreadedMode = numberOfCommonPoolThreads == 0 && actualCommonPoolParallelism == 1; - if (!isSingleThreadedMode && actualCommonPoolParallelism != numberOfCommonPoolThreads) { - String warning = "Failed to set parallelism of common pool (actual parallelism is %s).".formatted(actualCommonPoolParallelism); - assert false : warning; - LogUtils.warning(warning); - } + /* + * The main thread always helps to process tasks submitted to the common pool (e.g., see + * ForkJoinPool#awaitTermination()), so subtract one from the number of threads. The common + * pool can be disabled "by setting the parallelism property to zero" (see ForkJoinPool's + * javadoc). + */ + int numberOfCommonPoolThreads = NativeImageOptions.NumberOfThreads.getValueOrDefault(optionValues.getMap()) - 1; + String commonPoolParallelismProperty = "java.util.concurrent.ForkJoinPool.common.parallelism"; + assert System.getProperty(commonPoolParallelismProperty) == null : commonPoolParallelismProperty + " already set"; + System.setProperty(commonPoolParallelismProperty, "" + numberOfCommonPoolThreads); + int actualCommonPoolParallelism = ForkJoinPool.commonPool().getParallelism(); + /* + * getParallelism() returns at least 1, even in single-threaded mode where common pool is + * disabled. + */ + boolean isSingleThreadedMode = numberOfCommonPoolThreads == 0 && actualCommonPoolParallelism == 1; + if (!isSingleThreadedMode && actualCommonPoolParallelism != numberOfCommonPoolThreads) { + String warning = "Failed to set parallelism of common pool (actual parallelism is %s).".formatted(actualCommonPoolParallelism); + assert false : warning; + LogUtils.warning(warning); } }