Merge

Tue, 07 Feb 2017 11:16:47 -0800

author
asaha
date
Tue, 07 Feb 2017 11:16:47 -0800
changeset 8783
4649a1517487
parent 8782
923de3f490e5
parent 8750
46ba0d78c1fc
child 8784
15af9b4ac654
child 8928
c468dc338392

Merge

.hgtags file | annotate | diff | comparison | revisions
     1.1 --- a/.hgtags	Mon Jan 23 16:38:33 2017 -0800
     1.2 +++ b/.hgtags	Tue Feb 07 11:16:47 2017 -0800
     1.3 @@ -950,4 +950,6 @@
     1.4  ef90c721a4e59b01ca36f25619010a1afe9ed4d5 jdk8u131-b02
     1.5  0ca47d0811b01ecf8651b6045a1e33a4a9bed0ee jdk8u131-b03
     1.6  dab1d597165207e14b6886b1823c1e990bc776a3 jdk8u131-b04
     1.7 +c965fc1aa840a0903709ad69aa0e2100330ccd84 jdk8u131-b05
     1.8 +6e4cfbc7534f83902692132efb61683528c04a59 jdk8u131-b06
     1.9  692bc6b674dcab72453de08ee9da0856a7e41c0f jdk8u141-b00
     2.1 --- a/src/os/linux/vm/globals_linux.hpp	Mon Jan 23 16:38:33 2017 -0800
     2.2 +++ b/src/os/linux/vm/globals_linux.hpp	Tue Feb 07 11:16:47 2017 -0800
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
     2.6 + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -47,7 +47,10 @@
    2.11            "Load DLLs with executable-stack attribute in the VM Thread") \
    2.12                                                                          \
    2.13    product(bool, UseSHM, false,                                          \
    2.14 -          "Use SYSV shared memory for large pages")
    2.15 +          "Use SYSV shared memory for large pages")                     \
    2.16 +                                                                        \
    2.17 +  diagnostic(bool, PrintActiveCpus, false,                              \
    2.18 +          "Print the number of CPUs detected in os::active_processor_count")
    2.19  
    2.20  //
    2.21  // Defines Linux-specific default values. The flags are available on all
     3.1 --- a/src/os/linux/vm/os_linux.cpp	Mon Jan 23 16:38:33 2017 -0800
     3.2 +++ b/src/os/linux/vm/os_linux.cpp	Tue Feb 07 11:16:47 2017 -0800
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -104,6 +104,14 @@
    3.11  
    3.12  PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
    3.13  
    3.14 +#ifndef _GNU_SOURCE
    3.15 +  #define _GNU_SOURCE
    3.16 +  #include <sched.h>
    3.17 +  #undef _GNU_SOURCE
    3.18 +#else
    3.19 +  #include <sched.h>
    3.20 +#endif
    3.21 +
    3.22  // if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
    3.23  // getrusage() is prepared to handle the associated failure.
    3.24  #ifndef RUSAGE_THREAD
    3.25 @@ -1067,29 +1075,30 @@
    3.26  
    3.27  // Locate initial thread stack. This special handling of initial thread stack
    3.28  // is needed because pthread_getattr_np() on most (all?) Linux distros returns
    3.29 -// bogus value for initial thread.
    3.30 +// bogus value for the primordial process thread. While the launcher has created
    3.31 +// the VM in a new thread since JDK 6, we still have to allow for the use of the
    3.32 +// JNI invocation API from a primordial thread.
    3.33  void os::Linux::capture_initial_stack(size_t max_size) {
    3.34 -  // stack size is the easy part, get it from RLIMIT_STACK
    3.35 -  size_t stack_size;
    3.36 +
    3.37 +  // max_size is either 0 (which means accept OS default for thread stacks) or
    3.38 +  // a user-specified value known to be at least the minimum needed. If we
    3.39 +  // are actually on the primordial thread we can make it appear that we have a
    3.40 +  // smaller max_size stack by inserting the guard pages at that location. But we
    3.41 +  // cannot do anything to emulate a larger stack than what has been provided by
    3.42 +  // the OS or threading library. In fact if we try to use a stack greater than
    3.43 +  // what is set by rlimit then we will crash the hosting process.
    3.44 +
    3.45 +  // Maximum stack size is the easy part, get it from RLIMIT_STACK.
    3.46 +  // If this is "unlimited" then it will be a huge value.
    3.47    struct rlimit rlim;
    3.48    getrlimit(RLIMIT_STACK, &rlim);
    3.49 -  stack_size = rlim.rlim_cur;
    3.50 +  size_t stack_size = rlim.rlim_cur;
    3.51  
    3.52    // 6308388: a bug in ld.so will relocate its own .data section to the
    3.53    //   lower end of primordial stack; reduce ulimit -s value a little bit
    3.54    //   so we won't install guard page on ld.so's data section.
    3.55    stack_size -= 2 * page_size();
    3.56  
    3.57 -  // 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat
    3.58 -  //   7.1, in both cases we will get 2G in return value.
    3.59 -  // 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0,
    3.60 -  //   SuSE 7.2, Debian) can not handle alternate signal stack correctly
    3.61 -  //   for initial thread if its stack size exceeds 6M. Cap it at 2M,
    3.62 -  //   in case other parts in glibc still assumes 2M max stack size.
    3.63 -  // FIXME: alt signal stack is gone, maybe we can relax this constraint?
    3.64 -  // Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small
    3.65 -  if (stack_size > 2 * K * K IA64_ONLY(*2))
    3.66 -      stack_size = 2 * K * K IA64_ONLY(*2);
    3.67    // Try to figure out where the stack base (top) is. This is harder.
    3.68    //
    3.69    // When an application is started, glibc saves the initial stack pointer in
    3.70 @@ -1249,14 +1258,18 @@
    3.71    // stack_top could be partially down the page so align it
    3.72    stack_top = align_size_up(stack_top, page_size());
    3.73  
    3.74 -  if (max_size && stack_size > max_size) {
    3.75 -     _initial_thread_stack_size = max_size;
    3.76 +  // Allowed stack value is minimum of max_size and what we derived from rlimit
    3.77 +  if (max_size > 0) {
    3.78 +    _initial_thread_stack_size = MIN2(max_size, stack_size);
    3.79    } else {
    3.80 -     _initial_thread_stack_size = stack_size;
    3.81 +    // Accept the rlimit max, but if stack is unlimited then it will be huge, so
    3.82 +    // clamp it at 8MB as we do on Solaris
    3.83 +    _initial_thread_stack_size = MIN2(stack_size, 8*M);
    3.84    }
    3.85  
    3.86    _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size());
    3.87    _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size;
    3.88 +  assert(_initial_thread_stack_bottom < (address)stack_top, "overflow!");
    3.89  }
    3.90  
    3.91  ////////////////////////////////////////////////////////////////////////////////
    3.92 @@ -5016,12 +5029,42 @@
    3.93    }
    3.94  };
    3.95  
    3.96 +static int os_cpu_count(const cpu_set_t* cpus) {
    3.97 +  int count = 0;
    3.98 +  // only look up to the number of configured processors
    3.99 +  for (int i = 0; i < os::processor_count(); i++) {
   3.100 +    if (CPU_ISSET(i, cpus)) {
   3.101 +      count++;
   3.102 +    }
   3.103 +  }
   3.104 +  return count;
   3.105 +}
   3.106 +
   3.107 +// Get the current number of available processors for this process.
   3.108 +// This value can change at any time during a process's lifetime.
   3.109 +// sched_getaffinity gives an accurate answer as it accounts for cpusets.
   3.110 +// If anything goes wrong we fallback to returning the number of online
   3.111 +// processors - which can be greater than the number available to the process.
   3.112  int os::active_processor_count() {
   3.113 -  // Linux doesn't yet have a (official) notion of processor sets,
   3.114 -  // so just return the number of online processors.
   3.115 -  int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
   3.116 -  assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
   3.117 -  return online_cpus;
   3.118 +  cpu_set_t cpus;  // can represent at most 1024 (CPU_SETSIZE) processors
   3.119 +  int cpus_size = sizeof(cpu_set_t);
   3.120 +  int cpu_count = 0;
   3.121 +
   3.122 +  // pid 0 means the current thread - which we have to assume represents the process
   3.123 +  if (sched_getaffinity(0, cpus_size, &cpus) == 0) {
   3.124 +    cpu_count = os_cpu_count(&cpus);
   3.125 +    if (PrintActiveCpus) {
   3.126 +      tty->print_cr("active_processor_count: sched_getaffinity processor count: %d", cpu_count);
   3.127 +    }
   3.128 +  }
   3.129 +  else {
   3.130 +    cpu_count = ::sysconf(_SC_NPROCESSORS_ONLN);
   3.131 +    warning("sched_getaffinity failed (%s)- using online processor count (%d) "
   3.132 +            "which may exceed available processors", strerror(errno), cpu_count);
   3.133 +  }
   3.134 +
   3.135 +  assert(cpu_count > 0 && cpu_count <= processor_count(), "sanity check");
   3.136 +  return cpu_count;
   3.137  }
   3.138  
   3.139  void os::set_native_thread_name(const char *name) {
     4.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Mon Jan 23 16:38:33 2017 -0800
     4.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Feb 07 11:16:47 2017 -0800
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
     4.6 + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
     4.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8   *
     4.9   * This code is free software; you can redistribute it and/or modify it
    4.10 @@ -631,11 +631,10 @@
    4.11        double overall_cm_overhead =
    4.12          (double) MaxGCPauseMillis * marking_overhead /
    4.13          (double) GCPauseIntervalMillis;
    4.14 -      double cpu_ratio = 1.0 / (double) os::processor_count();
    4.15 +      double cpu_ratio = 1.0 / os::initial_active_processor_count();
    4.16        double marking_thread_num = ceil(overall_cm_overhead / cpu_ratio);
    4.17        double marking_task_overhead =
    4.18 -        overall_cm_overhead / marking_thread_num *
    4.19 -                                                (double) os::processor_count();
    4.20 +        overall_cm_overhead / marking_thread_num * os::initial_active_processor_count();
    4.21        double sleep_factor =
    4.22                           (1.0 - marking_task_overhead) / marking_task_overhead;
    4.23  
     5.1 --- a/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp	Mon Jan 23 16:38:33 2017 -0800
     5.2 +++ b/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp	Tue Feb 07 11:16:47 2017 -0800
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
     5.6 + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -80,7 +80,7 @@
    5.11  
    5.12  // Determines how many mutator threads can process the buffers in parallel.
    5.13  uint DirtyCardQueueSet::num_par_ids() {
    5.14 -  return (uint)os::processor_count();
    5.15 +  return (uint)os::initial_active_processor_count();
    5.16  }
    5.17  
    5.18  void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock,
     6.1 --- a/src/share/vm/runtime/arguments.cpp	Mon Jan 23 16:38:33 2017 -0800
     6.2 +++ b/src/share/vm/runtime/arguments.cpp	Tue Feb 07 11:16:47 2017 -0800
     6.3 @@ -1,5 +1,5 @@
     6.4  /*
     6.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     6.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     6.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.8   *
     6.9   * This code is free software; you can redistribute it and/or modify it
    6.10 @@ -1768,10 +1768,39 @@
    6.11      FLAG_SET_CMDLINE(uintx, MaxRAMFraction, DefaultMaxRAMFraction);
    6.12    }
    6.13  
    6.14 -  const julong phys_mem =
    6.15 +  julong phys_mem =
    6.16      FLAG_IS_DEFAULT(MaxRAM) ? MIN2(os::physical_memory(), (julong)MaxRAM)
    6.17                              : (julong)MaxRAM;
    6.18  
    6.19 +  // Experimental support for CGroup memory limits
    6.20 +  if (UseCGroupMemoryLimitForHeap) {
    6.21 +    // This is a rough indicator that a CGroup limit may be in force
    6.22 +    // for this process
    6.23 +    const char* lim_file = "/sys/fs/cgroup/memory/memory.limit_in_bytes";
    6.24 +    FILE *fp = fopen(lim_file, "r");
    6.25 +    if (fp != NULL) {
    6.26 +      julong cgroup_max = 0;
    6.27 +      int ret = fscanf(fp, JULONG_FORMAT, &cgroup_max);
    6.28 +      if (ret == 1 && cgroup_max > 0) {
    6.29 +        // If unlimited, cgroup_max will be a very large, but unspecified
    6.30 +        // value, so use initial phys_mem as a limit
    6.31 +        if (PrintGCDetails && Verbose) {
    6.32 +          // Cannot use gclog_or_tty yet.
    6.33 +          tty->print_cr("Setting phys_mem to the min of cgroup limit ("
    6.34 +                        JULONG_FORMAT "MB) and initial phys_mem ("
    6.35 +                        JULONG_FORMAT "MB)", cgroup_max/M, phys_mem/M);
    6.36 +        }
    6.37 +        phys_mem = MIN2(cgroup_max, phys_mem);
    6.38 +      } else {
    6.39 +        warning("Unable to read/parse cgroup memory limit from %s: %s",
    6.40 +                lim_file, errno != 0 ? strerror(errno) : "unknown error");
    6.41 +      }
    6.42 +      fclose(fp);
    6.43 +    } else {
    6.44 +      warning("Unable to open cgroup memory limit file %s (%s)", lim_file, strerror(errno));
    6.45 +    }
    6.46 +  }
    6.47 +
    6.48    // If the maximum heap size has not been set with -Xmx,
    6.49    // then set it as fraction of the size of physical memory,
    6.50    // respecting the maximum and minimum sizes of the heap.
     7.1 --- a/src/share/vm/runtime/globals.hpp	Mon Jan 23 16:38:33 2017 -0800
     7.2 +++ b/src/share/vm/runtime/globals.hpp	Tue Feb 07 11:16:47 2017 -0800
     7.3 @@ -1,5 +1,5 @@
     7.4  /*
     7.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     7.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     7.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.8   *
     7.9   * This code is free software; you can redistribute it and/or modify it
    7.10 @@ -2068,6 +2068,10 @@
    7.11            "Maximum ergonomically set heap size (in bytes); zero means use " \
    7.12            "MaxRAM / MaxRAMFraction")                                        \
    7.13                                                                              \
    7.14 +  experimental(bool, UseCGroupMemoryLimitForHeap, false,                    \
    7.15 +          "Use CGroup memory limit as physical memory limit for heap "      \
    7.16 +          "sizing")                                                         \
    7.17 +                                                                            \
    7.18    product(uintx, MaxRAMFraction, 4,                                         \
    7.19            "Maximum fraction (1/n) of real memory used for maximum heap "    \
    7.20            "size")                                                           \
     8.1 --- a/src/share/vm/runtime/os.cpp	Mon Jan 23 16:38:33 2017 -0800
     8.2 +++ b/src/share/vm/runtime/os.cpp	Tue Feb 07 11:16:47 2017 -0800
     8.3 @@ -1,5 +1,5 @@
     8.4  /*
     8.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     8.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     8.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.8   *
     8.9   * This code is free software; you can redistribute it and/or modify it
    8.10 @@ -78,6 +78,7 @@
    8.11  uintptr_t         os::_serialize_page_mask = 0;
    8.12  long              os::_rand_seed          = 1;
    8.13  int               os::_processor_count    = 0;
    8.14 +int               os::_initial_active_processor_count = 0;
    8.15  size_t            os::_page_sizes[os::page_sizes_max];
    8.16  
    8.17  #ifndef PRODUCT
    8.18 @@ -322,6 +323,7 @@
    8.19  }
    8.20  
    8.21  void os::init_before_ergo() {
    8.22 +  initialize_initial_active_processor_count();
    8.23    // We need to initialize large page support here because ergonomics takes some
    8.24    // decisions depending on large page support and the calculated large page size.
    8.25    large_page_init();
    8.26 @@ -835,7 +837,11 @@
    8.27    st->print("CPU:");
    8.28    st->print("total %d", os::processor_count());
    8.29    // It's not safe to query number of active processors after crash
    8.30 -  // st->print("(active %d)", os::active_processor_count());
    8.31 +  // st->print("(active %d)", os::active_processor_count()); but we can
    8.32 +  // print the initial number of active processors.
    8.33 +  // We access the raw value here because the assert in the accessor will
    8.34 +  // fail if the crash occurs before initialization of this value.
    8.35 +  st->print(" (initial active %d)", _initial_active_processor_count);
    8.36    st->print(" %s", VM_Version::cpu_features());
    8.37    st->cr();
    8.38    pd_print_cpu_info(st);
    8.39 @@ -1418,6 +1424,11 @@
    8.40    return result;
    8.41  }
    8.42  
    8.43 +void os::initialize_initial_active_processor_count() {
    8.44 +  assert(_initial_active_processor_count == 0, "Initial active processor count already set.");
    8.45 +  _initial_active_processor_count = active_processor_count();
    8.46 +}
    8.47 +
    8.48  void os::SuspendedThreadTask::run() {
    8.49    assert(Threads_lock->owned_by_self() || (_thread == VMThread::vm_thread()), "must have threads lock to call this");
    8.50    internal_do_task();
     9.1 --- a/src/share/vm/runtime/os.hpp	Mon Jan 23 16:38:33 2017 -0800
     9.2 +++ b/src/share/vm/runtime/os.hpp	Tue Feb 07 11:16:47 2017 -0800
     9.3 @@ -151,6 +151,7 @@
     9.4  
     9.5    static size_t page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned);
     9.6  
     9.7 +  static void initialize_initial_active_processor_count();
     9.8   public:
     9.9    static void init(void);                      // Called before command line parsing
    9.10    static void init_before_ergo(void);          // Called after command line parsing
    9.11 @@ -238,6 +239,13 @@
    9.12    // Note that on some OSes this can change dynamically.
    9.13    static int active_processor_count();
    9.14  
    9.15 +  // At startup the number of active CPUs this process is allowed to run on.
    9.16 +  // This value does not change dynamically. May be different from active_processor_count().
    9.17 +  static int initial_active_processor_count() {
    9.18 +    assert(_initial_active_processor_count > 0, "Initial active processor count not set yet.");
    9.19 +    return _initial_active_processor_count;
    9.20 +  }
    9.21 +
    9.22    // Bind processes to processors.
    9.23    //     This is a two step procedure:
    9.24    //     first you generate a distribution of processes to processors,
    9.25 @@ -975,8 +983,9 @@
    9.26  
    9.27  
    9.28   protected:
    9.29 -  static long _rand_seed;                   // seed for random number generator
    9.30 -  static int _processor_count;              // number of processors
    9.31 +  static long _rand_seed;                     // seed for random number generator
    9.32 +  static int _processor_count;                // number of processors
    9.33 +  static int _initial_active_processor_count; // number of active processors during initialization.
    9.34  
    9.35    static char* format_boot_path(const char* format_string,
    9.36                                  const char* home,
    10.1 --- a/src/share/vm/runtime/vm_version.cpp	Mon Jan 23 16:38:33 2017 -0800
    10.2 +++ b/src/share/vm/runtime/vm_version.cpp	Tue Feb 07 11:16:47 2017 -0800
    10.3 @@ -1,5 +1,5 @@
    10.4  /*
    10.5 - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
    10.6 + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
    10.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.8   *
    10.9   * This code is free software; you can redistribute it and/or modify it
   10.10 @@ -296,7 +296,7 @@
   10.11      // processor after the first 8.  For example, on a 72 cpu machine
   10.12      // and a chosen fraction of 5/8
   10.13      // use 8 + (72 - 8) * (5/8) == 48 worker threads.
   10.14 -    unsigned int ncpus = (unsigned int) os::active_processor_count();
   10.15 +    unsigned int ncpus = (unsigned int) os::initial_active_processor_count();
   10.16      return (ncpus <= switch_pt) ?
   10.17             ncpus :
   10.18            (switch_pt + ((ncpus - switch_pt) * num) / den);
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/test/runtime/os/AvailableProcessors.java	Tue Feb 07 11:16:47 2017 -0800
    11.3 @@ -0,0 +1,103 @@
    11.4 +/*
    11.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 + *
    11.8 + * This code is free software; you can redistribute it and/or modify it
    11.9 + * under the terms of the GNU General Public License version 2 only, as
   11.10 + * published by the Free Software Foundation.
   11.11 + *
   11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.15 + * version 2 for more details (a copy is included in the LICENSE file that
   11.16 + * accompanied this code).
   11.17 + *
   11.18 + * You should have received a copy of the GNU General Public License version
   11.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.21 + *
   11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.23 + * or visit www.oracle.com if you need additional information or have any
   11.24 + * questions.
   11.25 + */
   11.26 +import java.io.File;
   11.27 +import com.oracle.java.testlibrary.ProcessTools;
   11.28 +import com.oracle.java.testlibrary.OutputAnalyzer;
   11.29 +import java.util.ArrayList;
   11.30 +
   11.31 +/*
   11.32 + * @test
   11.33 + * @bug 6515172
   11.34 + * @summary Check that availableProcessors reports the correct value when running in a cpuset on linux
   11.35 + * @requires os.family == "linux"
   11.36 + * @library /testlibrary
   11.37 + * @build com.oracle.java.testlibrary.*
   11.38 + * @run driver AvailableProcessors
   11.39 + */
   11.40 +public class AvailableProcessors {
   11.41 +
   11.42 +    static final String SUCCESS_STRING = "Found expected processors: ";
   11.43 +
   11.44 +    public static void main(String[] args) throws Throwable {
   11.45 +        if (args.length > 0)
   11.46 +            checkProcessors(Integer.parseInt(args[0]));
   11.47 +        else {
   11.48 +            // run ourselves under different cpu configurations
   11.49 +            // using the taskset command
   11.50 +            String taskset;
   11.51 +            final String taskset1 = "/bin/taskset";
   11.52 +            final String taskset2 = "/usr/bin/taskset";
   11.53 +            if (new File(taskset1).exists())
   11.54 +                taskset = taskset1;
   11.55 +            else if (new File(taskset2).exists())
   11.56 +                taskset = taskset2;
   11.57 +            else {
   11.58 +                System.out.println("Skipping test: could not find taskset command");
   11.59 +                return;
   11.60 +            }
   11.61 +
   11.62 +            int available = Runtime.getRuntime().availableProcessors();
   11.63 +
   11.64 +            if (available == 1) {
   11.65 +                System.out.println("Skipping test: only one processor available");
   11.66 +                return;
   11.67 +            }
   11.68 +
   11.69 +            // Get the java command we want to execute
   11.70 +            // Enable logging for easier failure diagnosis
   11.71 +            ProcessBuilder master =
   11.72 +                    ProcessTools.createJavaProcessBuilder(false,
   11.73 +                                                          "-XX:+UnlockDiagnosticVMOptions",
   11.74 +                                                          "-XX:+PrintActiveCpus",
   11.75 +                                                          "AvailableProcessors");
   11.76 +
   11.77 +            int[] expected = new int[] { 1, available/2, available-1, available };
   11.78 +
   11.79 +            for (int i : expected) {
   11.80 +                System.out.println("Testing for " + i + " processors ...");
   11.81 +                int max = i - 1;
   11.82 +                ArrayList<String> cmdline = new ArrayList<>(master.command());
   11.83 +                // prepend taskset command
   11.84 +                cmdline.add(0, "0-" + max);
   11.85 +                cmdline.add(0, "-c");
   11.86 +                cmdline.add(0, taskset);
   11.87 +                // append expected processor count
   11.88 +                cmdline.add(String.valueOf(i));
   11.89 +                ProcessBuilder pb = new ProcessBuilder(cmdline);
   11.90 +                System.out.println("Final command line: " +
   11.91 +                                   ProcessTools.getCommandLine(pb));
   11.92 +                OutputAnalyzer output = ProcessTools.executeProcess(pb);
   11.93 +                output.shouldContain(SUCCESS_STRING);
   11.94 +            }
   11.95 +        }
   11.96 +    }
   11.97 +
   11.98 +    static void checkProcessors(int expected) {
   11.99 +        int available = Runtime.getRuntime().availableProcessors();
  11.100 +        if (available != expected)
  11.101 +            throw new Error("Expected " + expected + " processors, but found "
  11.102 +                            + available);
  11.103 +        else
  11.104 +            System.out.println(SUCCESS_STRING + available);
  11.105 +    }
  11.106 +}

mercurial