Mercurial > hg > icedtea8-forest > hotspot
changeset 9581:58d961f47dd4 jdk8u122-b02
Merge
author | robm |
---|---|
date | Fri, 23 Sep 2016 18:19:50 +0000 |
parents | 020cb72be8b7 (current diff) 3ed8945db9c3 (diff) |
children | d3b4ef97a518 f7b4a17a9d49 fa9ea9d2801f |
files | |
diffstat | 7 files changed, 163 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/src/os/linux/vm/globals_linux.hpp Mon Sep 19 21:11:55 2016 -0700 +++ b/src/os/linux/vm/globals_linux.hpp Fri Sep 23 18:19:50 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -47,7 +47,10 @@ "Load DLLs with executable-stack attribute in the VM Thread") \ \ product(bool, UseSHM, false, \ - "Use SYSV shared memory for large pages") + "Use SYSV shared memory for large pages") \ + \ + diagnostic(bool, PrintActiveCpus, false, \ + "Print the number of CPUs detected in os::active_processor_count") // // Defines Linux-specific default values. The flags are available on all
--- a/src/os/linux/vm/os_linux.cpp Mon Sep 19 21:11:55 2016 -0700 +++ b/src/os/linux/vm/os_linux.cpp Fri Sep 23 18:19:50 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -104,6 +104,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 @@ -2846,7 +2854,7 @@ // in the library. const size_t BitsPerCLong = sizeof(long) * CHAR_BIT; - size_t cpu_num = os::active_processor_count(); + size_t cpu_num = processor_count(); size_t cpu_map_size = NCPUS / BitsPerCLong; size_t cpu_map_valid_size = MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size); @@ -5016,12 +5024,42 @@ } }; +static int os_cpu_count(const cpu_set_t* cpus) { + int count = 0; + // only look up to the number of configured processors + for (int i = 0; i < os::processor_count(); i++) { + if (CPU_ISSET(i, cpus)) { + count++; + } + } + return count; +} + +// 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 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::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 + int cpus_size = sizeof(cpu_set_t); + int cpu_count = 0; + + // pid 0 means the current thread - which we have to assume represents the process + if (sched_getaffinity(0, cpus_size, &cpus) == 0) { + cpu_count = os_cpu_count(&cpus); + if (PrintActiveCpus) { + tty->print_cr("active_processor_count: sched_getaffinity processor count: %d", cpu_count); + } + } + else { + cpu_count = ::sysconf(_SC_NPROCESSORS_ONLN); + warning("sched_getaffinity failed (%s)- using online processor count (%d) " + "which may exceed available processors", strerror(errno), cpu_count); + } + + assert(cpu_count > 0 && cpu_count <= processor_count(), "sanity check"); + return cpu_count; } void os::set_native_thread_name(const char *name) {
--- a/src/share/vm/classfile/systemDictionary.cpp Mon Sep 19 21:11:55 2016 -0700 +++ b/src/share/vm/classfile/systemDictionary.cpp Fri Sep 23 18:19:50 2016 +0000 @@ -1084,15 +1084,18 @@ THREAD); const char* pkg = "java/"; + size_t pkglen = strlen(pkg); if (!HAS_PENDING_EXCEPTION && !class_loader.is_null() && parsed_name != NULL && - !strncmp((const char*)parsed_name->bytes(), pkg, strlen(pkg))) { + parsed_name->utf8_length() >= (int)pkglen && + !strncmp((const char*)parsed_name->bytes(), pkg, pkglen)) { // It is illegal to define classes in the "java." package from // JVM_DefineClass or jni_DefineClass unless you're the bootclassloader ResourceMark rm(THREAD); char* name = parsed_name->as_C_string(); char* index = strrchr(name, '/'); + assert(index != NULL, "must be"); *index = '\0'; // chop to just the package name while ((index = strchr(name, '/')) != NULL) { *index = '.'; // replace '/' with '.' in package name
--- a/src/share/vm/compiler/compileBroker.cpp Mon Sep 19 21:11:55 2016 -0700 +++ b/src/share/vm/compiler/compileBroker.cpp Fri Sep 23 18:19:50 2016 +0000 @@ -1851,6 +1851,10 @@ tty->print_cr("Opening compilation log %s", file_name); } CompileLog* log = new(ResourceObj::C_HEAP, mtCompiler) CompileLog(file_name, fp, thread_id); + if (log == NULL) { + fclose(fp); + return; + } thread->init_log(log); if (xtty != NULL) {
--- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp Mon Sep 19 21:11:55 2016 -0700 +++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp Fri Sep 23 18:19:50 2016 +0000 @@ -171,7 +171,7 @@ ParallelScavengeHeap* heap = PSParallelCompact::gc_heap(); uint parallel_gc_threads = heap->gc_task_manager()->workers(); uint active_gc_threads = heap->gc_task_manager()->active_workers(); - RegionTaskQueueSet* qset = ParCompactionManager::region_array(); + OopTaskQueueSet* qset = ParCompactionManager::stack_array(); ParallelTaskTerminator terminator(active_gc_threads, qset); GCTaskQueue* q = GCTaskQueue::create(); for(uint i=0; i<parallel_gc_threads; i++) {
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Mon Sep 19 21:11:55 2016 -0700 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Fri Sep 23 18:19:50 2016 +0000 @@ -2355,7 +2355,7 @@ ParallelScavengeHeap* heap = gc_heap(); uint parallel_gc_threads = heap->gc_task_manager()->workers(); uint active_gc_threads = heap->gc_task_manager()->active_workers(); - TaskQueueSetSuper* qset = ParCompactionManager::region_array(); + TaskQueueSetSuper* qset = ParCompactionManager::stack_array(); ParallelTaskTerminator terminator(active_gc_threads, qset); PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/os/AvailableProcessors.java Fri Sep 23 18:19:50 2016 +0000 @@ -0,0 +1,103 @@ +/* + * 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 com.oracle.java.testlibrary.ProcessTools; +import com.oracle.java.testlibrary.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 com.oracle.java.testlibrary.* + * @run driver AvailableProcessors + */ +public class AvailableProcessors { + + static final String SUCCESS_STRING = "Found expected processors: "; + + public static void main(String[] args) throws Throwable { + 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, + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+PrintActiveCpus", + "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); + } +}