aboutsummaryrefslogtreecommitdiffstats
path: root/community/openjdk8/icedtea-JDK-6515172_1_apply-jdk9-version.patch
diff options
context:
space:
mode:
Diffstat (limited to 'community/openjdk8/icedtea-JDK-6515172_1_apply-jdk9-version.patch')
-rw-r--r--community/openjdk8/icedtea-JDK-6515172_1_apply-jdk9-version.patch221
1 files changed, 221 insertions, 0 deletions
diff --git a/community/openjdk8/icedtea-JDK-6515172_1_apply-jdk9-version.patch b/community/openjdk8/icedtea-JDK-6515172_1_apply-jdk9-version.patch
new file mode 100644
index 00000000000..5c4b9c7d3e0
--- /dev/null
+++ b/community/openjdk8/icedtea-JDK-6515172_1_apply-jdk9-version.patch
@@ -0,0 +1,221 @@
+From 1875f65a5434aa89c559076031b88a3cb060acc4 Mon Sep 17 00:00:00 2001
+From: David Holmes <dholmes@openjdk.org>
+Date: Fri, 29 Jan 2016 05:32:12 -0500
+Subject: [PATCH] 6515172: Runtime.availableProcessors() ignores Linux taskset
+ command
+
+Extract processor count from sched_getaffinity mask
+
+Reviewed-by: dcubed, stuefe, gthornbr
+---
+ hotspot/src/os/linux/vm/globals_linux.hpp | 7 +-
+ hotspot/src/os/linux/vm/os_linux.cpp | 81 ++++++++++++--
+ hotspot/src/share/vm/logging/logTag.hpp | 3 +-
+ .../test/runtime/os/AvailableProcessors.java | 102 ++++++++++++++++++
+ 4 files changed, 184 insertions(+), 9 deletions(-)
+ create mode 100644 hotspot/test/runtime/os/AvailableProcessors.java
+
+diff --git a/hotspot/src/os/linux/vm/globals_linux.hpp b/hotspot/src/os/linux/vm/globals_linux.hpp
+index 29e450f8db..05f4c18133 100644
+--- openjdk/hotspot/src/os/linux/vm/globals_linux.hpp
++++ openjdk/hotspot/src/os/linux/vm/globals_linux.hpp
+@@ -49,6 +49,9 @@
+ product(bool, UseSHM, false, \
+ "Use SYSV shared memory for large pages") \
+ \
++ diagnostic(bool, UseCpuAllocPath, false, \
++ "Use CPU_ALLOC code path in os::active_processor_count ") \
++ \
+ product(bool, UseContainerSupport, true, \
+ "Enable detection and runtime container configuration support") \
+ \
+diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
+index 7e01a577d5..61406a11dd 100644
+--- openjdk/hotspot/src/os/linux/vm/os_linux.cpp
++++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp
+@@ -106,6 +107,14 @@
+
+ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+
++#ifndef _GNU_SOURCE
++ #define _GNU_SOURCE
++ #include <sched.h>
++ #undef _GNU_SOURCE
++#else
++ #include <sched.h>
++#endif
++
+ // if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
+ // getrusage() is prepared to handle the associated failure.
+ #ifndef RUSAGE_THREAD
+@@ -5335,12 +5344,57 @@
+ }
+ };
+
++// Get the current number of available processors for this process.
++// This value can change at any time during a process's lifetime.
++// sched_getaffinity gives an accurate answer as it accounts for cpusets.
++// If it appears there may be more than 1024 processors then we do a
++// dynamic check - see 6515172 for details.
++// If anything goes wrong we fallback to returning the number of online
++// processors - which can be greater than the number available to the process.
+ int os::Linux::active_processor_count() {
+- // Linux doesn't yet have a (official) notion of processor sets,
+- // so just return the number of online processors.
+- int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
+- assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
+- return online_cpus;
++ cpu_set_t cpus; // can represent at most 1024 (CPU_SETSIZE) processors
++ cpu_set_t* cpus_p = &cpus;
++ int cpus_size = sizeof(cpu_set_t);
++
++ int configured_cpus = processor_count(); // upper bound on available cpus
++ int cpu_count = 0;
++
++ // To enable easy testing of the dynamic path on different platforms we
++ // introduce a diagnostic flag: UseCpuAllocPath
++ if (configured_cpus >= CPU_SETSIZE || UseCpuAllocPath) {
++ // kernel may use a mask bigger than cpu_set_t
++ cpus_p = CPU_ALLOC(configured_cpus);
++ if (cpus_p != NULL) {
++ cpus_size = CPU_ALLOC_SIZE(configured_cpus);
++ // zero it just to be safe
++ CPU_ZERO_S(cpus_size, cpus_p);
++ }
++ else {
++ // failed to allocate so fallback to online cpus
++ int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
++ return online_cpus;
++ }
++ }
++
++ // pid 0 means the current thread - which we have to assume represents the process
++ if (sched_getaffinity(0, cpus_size, cpus_p) == 0) {
++ if (cpus_p != &cpus) {
++ cpu_count = CPU_COUNT_S(cpus_size, cpus_p);
++ }
++ else {
++ cpu_count = CPU_COUNT(cpus_p);
++ }
++ }
++ else {
++ cpu_count = ::sysconf(_SC_NPROCESSORS_ONLN);
++ }
++
++ if (cpus_p != &cpus) {
++ CPU_FREE(cpus_p);
++ }
++
++ assert(cpu_count > 0 && cpu_count <= processor_count(), "sanity check");
++ return cpu_count;
+ }
+
+ // Determine the active processor count from one of
+diff --git a/hotspot/test/runtime/os/AvailableProcessors.java b/hotspot/test/runtime/os/AvailableProcessors.java
+new file mode 100644
+index 0000000000..4188a11d91
+--- /dev/null
++++ openjdk/hotspot/test/runtime/os/AvailableProcessors.java
+@@ -0,0 +1,102 @@
++/*
++ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++import java.io.File;
++import jdk.test.lib.ProcessTools;
++import jdk.test.lib.OutputAnalyzer;
++import java.util.ArrayList;
++
++/*
++ * @test
++ * @bug 6515172
++ * @summary Check that availableProcessors reports the correct value when running in a cpuset on linux
++ * @requires os.family == "linux"
++ * @library /testlibrary
++ * @build jdk.test.lib.*
++ * @run driver AvailableProcessors
++ */
++public class AvailableProcessors {
++
++ static final String SUCCESS_STRING = "Found expected processors: ";
++
++ public static void main(String[] args) throws Exception {
++ if (args.length > 0)
++ checkProcessors(Integer.parseInt(args[0]));
++ else {
++ // run ourselves under different cpu configurations
++ // using the taskset command
++ String taskset;
++ final String taskset1 = "/bin/taskset";
++ final String taskset2 = "/usr/bin/taskset";
++ if (new File(taskset1).exists())
++ taskset = taskset1;
++ else if (new File(taskset2).exists())
++ taskset = taskset2;
++ else {
++ System.out.println("Skipping test: could not find taskset command");
++ return;
++ }
++
++ int available = Runtime.getRuntime().availableProcessors();
++
++ if (available == 1) {
++ System.out.println("Skipping test: only one processor available");
++ return;
++ }
++
++ // Get the java command we want to execute
++ // Enable logging for easier failure diagnosis
++ ProcessBuilder master =
++ ProcessTools.createJavaProcessBuilder(false,
++ "-Xlog:os=trace",
++ "AvailableProcessors");
++
++ int[] expected = new int[] { 1, available/2, available-1, available };
++
++ for (int i : expected) {
++ System.out.println("Testing for " + i + " processors ...");
++ int max = i - 1;
++ ArrayList<String> cmdline = new ArrayList<>(master.command());
++ // prepend taskset command
++ cmdline.add(0, "0-" + max);
++ cmdline.add(0, "-c");
++ cmdline.add(0, taskset);
++ // append expected processor count
++ cmdline.add(String.valueOf(i));
++ ProcessBuilder pb = new ProcessBuilder(cmdline);
++ System.out.println("Final command line: " +
++ ProcessTools.getCommandLine(pb));
++ OutputAnalyzer output = ProcessTools.executeProcess(pb);
++ output.shouldContain(SUCCESS_STRING);
++ }
++ }
++ }
++
++ static void checkProcessors(int expected) {
++ int available = Runtime.getRuntime().availableProcessors();
++ if (available != expected)
++ throw new Error("Expected " + expected + " processors, but found "
++ + available);
++ else
++ System.out.println(SUCCESS_STRING + available);
++ }
++}