changeset 10858:22ec1c43273b

8227006: [linux] Runtime.availableProcessors execution time increased by factor of 100 Reviewed-by: andrew, sgehwolf Contributed-by: jdowland@redhat.com
author bobv
date Thu, 31 Oct 2019 19:32:41 +0000
parents 312e9cb580c5
children e5c6b19dd8fc
files src/os/linux/vm/osContainer_linux.cpp src/os/linux/vm/osContainer_linux.hpp
diffstat 2 files changed, 32 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/os/linux/vm/osContainer_linux.cpp	Wed Nov 18 06:50:30 2020 +0000
+++ b/src/os/linux/vm/osContainer_linux.cpp	Thu Oct 31 19:32:41 2019 +0000
@@ -34,12 +34,15 @@
 
 bool  OSContainer::_is_initialized   = false;
 bool  OSContainer::_is_containerized = false;
+int   OSContainer::_active_processor_count = 1;
 julong _unlimited_memory;
 
 class CgroupSubsystem: CHeapObj<mtInternal> {
  friend class OSContainer;
 
  private:
+    volatile jlong _next_check_counter;
+
     /* mountinfo contents */
     char *_root;
     char *_mount_point;
@@ -52,6 +55,7 @@
       _root = os::strdup(root);
       _mount_point = os::strdup(mountpoint);
       _path = NULL;
+      _next_check_counter = min_jlong;
     }
 
     /*
@@ -101,6 +105,14 @@
     }
 
     char *subsystem_path() { return _path; }
+
+    bool cache_has_expired() {
+      return os::elapsed_counter() > _next_check_counter;
+    }
+
+    void set_cache_expiry_time(jlong timeout) {
+      _next_check_counter = os::elapsed_counter() + timeout;
+    }
 };
 
 CgroupSubsystem* memory = NULL;
@@ -584,6 +596,17 @@
   int cpu_count, limit_count;
   int result;
 
+  // We use a cache with a timeout to avoid performing expensive
+  // computations in the event this function is called frequently.
+  // [See 8227006].
+  if (!cpu->cache_has_expired()) {
+    if (PrintContainerInfo) {
+      tty->print_cr("OSContainer::active_processor_count (cached): %d", OSContainer::_active_processor_count);
+    }
+
+    return OSContainer::_active_processor_count;
+  }
+
   cpu_count = limit_count = os::Linux::active_processor_count();
   int quota  = cpu_quota();
   int period = cpu_period();
@@ -622,6 +645,11 @@
   if (PrintContainerInfo) {
     tty->print_cr("OSContainer::active_processor_count: %d", result);
   }
+
+  // Update the value and reset the cache timeout
+  OSContainer::_active_processor_count = result;
+  cpu->set_cache_expiry_time(OSCONTAINER_CACHE_TIMEOUT);
+
   return result;
 }
 
--- a/src/os/linux/vm/osContainer_linux.hpp	Wed Nov 18 06:50:30 2020 +0000
+++ b/src/os/linux/vm/osContainer_linux.hpp	Thu Oct 31 19:32:41 2019 +0000
@@ -31,11 +31,15 @@
 
 #define OSCONTAINER_ERROR (-2)
 
+// 20ms timeout between re-reads of _active_processor_count.
+#define OSCONTAINER_CACHE_TIMEOUT (NANOSECS_PER_SEC/50)
+
 class OSContainer: AllStatic {
 
  private:
   static bool   _is_initialized;
   static bool   _is_containerized;
+  static int    _active_processor_count;
 
  public:
   static void init();