diff options
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.patch | 221 |
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); ++ } ++} |