< prev index next >
src/hotspot/os/linux/osContainer_linux.cpp
Print this page
@@ -52,16 +52,20 @@
*/
#define PER_CPU_SHARES 1024
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;
/* Constructed subsystem directory */
@@ -70,10 +74,11 @@
public:
CgroupSubsystem(char *root, char *mountpoint) {
_root = os::strdup(root);
_mount_point = os::strdup(mountpoint);
_path = NULL;
+ _next_check_counter = min_jlong;
}
/*
* Set directory to subsystem specific files based
* on the contents of the mountinfo and cgroup files.
@@ -119,10 +124,19 @@
}
}
}
char *subsystem_path() { return _path; }
+
+ bool check_cache_timeout() {
+ return os::elapsed_counter() > _next_check_counter;
+ }
+
+ void set_cache_timeout(jlong timeout) {
+ _next_check_counter = os::elapsed_counter() + timeout;
+ }
+
};
class CgroupMemorySubsystem: CgroupSubsystem {
friend class OSContainer;
@@ -130,35 +144,30 @@
/* Some container runtimes set limits via cgroup
* hierarchy. If set to true consider also memory.stat
* file if everything else seems unlimited */
bool _uses_mem_hierarchy;
volatile jlong _memory_limit_in_bytes;
- volatile jlong _next_check_counter;
public:
CgroupMemorySubsystem(char *root, char *mountpoint) : CgroupSubsystem::CgroupSubsystem(root, mountpoint) {
_uses_mem_hierarchy = false;
_memory_limit_in_bytes = -1;
- _next_check_counter = min_jlong;
}
bool is_hierarchical() { return _uses_mem_hierarchy; }
void set_hierarchical(bool value) { _uses_mem_hierarchy = value; }
- bool should_check_memory_limit() {
- return os::elapsed_counter() > _next_check_counter;
- }
jlong memory_limit_in_bytes() { return _memory_limit_in_bytes; }
void set_memory_limit_in_bytes(jlong value) {
_memory_limit_in_bytes = value;
// max memory limit is unlikely to change, but we want to remain
// responsive to configuration changes. A very short (20ms) grace time
// between re-read avoids excessive overhead during startup without
// significantly reducing the VMs ability to promptly react to reduced
// memory availability
- _next_check_counter = os::elapsed_counter() + (NANOSECS_PER_SEC/50);
+ set_cache_timeout(OSCONTAINER_CACHE_TIMEOUT);
}
};
CgroupMemorySubsystem* memory = NULL;
@@ -479,11 +488,11 @@
* memory limit in bytes or
* -1 for unlimited
* OSCONTAINER_ERROR for not supported
*/
jlong OSContainer::memory_limit_in_bytes() {
- if (!memory->should_check_memory_limit()) {
+ if (!memory->check_cache_timeout()) {
return memory->memory_limit_in_bytes();
}
jlong memory_limit = read_memory_limit_in_bytes();
// Update CgroupMemorySubsystem to avoid re-reading container settings too often
memory->set_memory_limit_in_bytes(memory_limit);
@@ -615,10 +624,18 @@
int OSContainer::active_processor_count() {
int quota_count = 0, share_count = 0;
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->check_cache_timeout()) {
+ log_trace(os, container)("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();
int share = cpu_shares();
@@ -647,10 +664,15 @@
limit_count = share_count;
}
result = MIN2(cpu_count, limit_count);
log_trace(os, container)("OSContainer::active_processor_count: %d", result);
+
+ // Update the value and set the cache timeout to 20ms.
+ OSContainer::_active_processor_count = result;
+ cpu->set_cache_timeout(OSCONTAINER_CACHE_TIMEOUT);
+
return result;
}
char * OSContainer::cpu_cpuset_cpus() {
GET_CONTAINER_INFO_CPTR(cptr, cpuset, "/cpuset.cpus",
< prev index next >