8227006: [linux] Runtime.availableProcessors execution time increased by factor of 100
Reviewed-by: dholmes, sgehwolf, redestad
This commit is contained in:
parent
7df849224b
commit
f5632e62b2
@ -54,12 +54,16 @@
|
|||||||
|
|
||||||
bool OSContainer::_is_initialized = false;
|
bool OSContainer::_is_initialized = false;
|
||||||
bool OSContainer::_is_containerized = false;
|
bool OSContainer::_is_containerized = false;
|
||||||
|
int OSContainer::_active_processor_count = 1;
|
||||||
julong _unlimited_memory;
|
julong _unlimited_memory;
|
||||||
|
|
||||||
class CgroupSubsystem: CHeapObj<mtInternal> {
|
class CgroupSubsystem: CHeapObj<mtInternal> {
|
||||||
friend class OSContainer;
|
friend class OSContainer;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
volatile jlong _next_check_counter;
|
||||||
|
|
||||||
/* mountinfo contents */
|
/* mountinfo contents */
|
||||||
char *_root;
|
char *_root;
|
||||||
char *_mount_point;
|
char *_mount_point;
|
||||||
@ -72,6 +76,7 @@ class CgroupSubsystem: CHeapObj<mtInternal> {
|
|||||||
_root = os::strdup(root);
|
_root = os::strdup(root);
|
||||||
_mount_point = os::strdup(mountpoint);
|
_mount_point = os::strdup(mountpoint);
|
||||||
_path = NULL;
|
_path = NULL;
|
||||||
|
_next_check_counter = min_jlong;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -121,6 +126,14 @@ class CgroupSubsystem: CHeapObj<mtInternal> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *subsystem_path() { return _path; }
|
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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CgroupMemorySubsystem: CgroupSubsystem {
|
class CgroupMemorySubsystem: CgroupSubsystem {
|
||||||
@ -132,31 +145,26 @@ class CgroupMemorySubsystem: CgroupSubsystem {
|
|||||||
* file if everything else seems unlimited */
|
* file if everything else seems unlimited */
|
||||||
bool _uses_mem_hierarchy;
|
bool _uses_mem_hierarchy;
|
||||||
volatile jlong _memory_limit_in_bytes;
|
volatile jlong _memory_limit_in_bytes;
|
||||||
volatile jlong _next_check_counter;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CgroupMemorySubsystem(char *root, char *mountpoint) : CgroupSubsystem::CgroupSubsystem(root, mountpoint) {
|
CgroupMemorySubsystem(char *root, char *mountpoint) : CgroupSubsystem::CgroupSubsystem(root, mountpoint) {
|
||||||
_uses_mem_hierarchy = false;
|
_uses_mem_hierarchy = false;
|
||||||
_memory_limit_in_bytes = -1;
|
_memory_limit_in_bytes = -1;
|
||||||
_next_check_counter = min_jlong;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_hierarchical() { return _uses_mem_hierarchy; }
|
bool is_hierarchical() { return _uses_mem_hierarchy; }
|
||||||
void set_hierarchical(bool value) { _uses_mem_hierarchy = value; }
|
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; }
|
jlong memory_limit_in_bytes() { return _memory_limit_in_bytes; }
|
||||||
void set_memory_limit_in_bytes(jlong value) {
|
void set_memory_limit_in_bytes(jlong value) {
|
||||||
_memory_limit_in_bytes = value;
|
_memory_limit_in_bytes = value;
|
||||||
// max memory limit is unlikely to change, but we want to remain
|
// max memory limit is unlikely to change, but we want to remain
|
||||||
// responsive to configuration changes. A very short (20ms) grace time
|
// responsive to configuration changes. A very short grace time
|
||||||
// between re-read avoids excessive overhead during startup without
|
// between re-read avoids excessive overhead during startup without
|
||||||
// significantly reducing the VMs ability to promptly react to reduced
|
// significantly reducing the VMs ability to promptly react to reduced
|
||||||
// memory availability
|
// memory availability
|
||||||
_next_check_counter = os::elapsed_counter() + (NANOSECS_PER_SEC/50);
|
set_cache_expiry_time(OSCONTAINER_CACHE_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -481,7 +489,7 @@ jlong OSContainer::uses_mem_hierarchy() {
|
|||||||
* OSCONTAINER_ERROR for not supported
|
* OSCONTAINER_ERROR for not supported
|
||||||
*/
|
*/
|
||||||
jlong OSContainer::memory_limit_in_bytes() {
|
jlong OSContainer::memory_limit_in_bytes() {
|
||||||
if (!memory->should_check_memory_limit()) {
|
if (!memory->cache_has_expired()) {
|
||||||
return memory->memory_limit_in_bytes();
|
return memory->memory_limit_in_bytes();
|
||||||
}
|
}
|
||||||
jlong memory_limit = read_memory_limit_in_bytes();
|
jlong memory_limit = read_memory_limit_in_bytes();
|
||||||
@ -617,6 +625,14 @@ int OSContainer::active_processor_count() {
|
|||||||
int cpu_count, limit_count;
|
int cpu_count, limit_count;
|
||||||
int result;
|
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()) {
|
||||||
|
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();
|
cpu_count = limit_count = os::Linux::active_processor_count();
|
||||||
int quota = cpu_quota();
|
int quota = cpu_quota();
|
||||||
int period = cpu_period();
|
int period = cpu_period();
|
||||||
@ -649,6 +665,11 @@ int OSContainer::active_processor_count() {
|
|||||||
|
|
||||||
result = MIN2(cpu_count, limit_count);
|
result = MIN2(cpu_count, limit_count);
|
||||||
log_trace(os, container)("OSContainer::active_processor_count: %d", result);
|
log_trace(os, container)("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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,11 +31,16 @@
|
|||||||
|
|
||||||
#define OSCONTAINER_ERROR (-2)
|
#define OSCONTAINER_ERROR (-2)
|
||||||
|
|
||||||
|
// 20ms timeout between re-reads of memory limit and _active_processor_count.
|
||||||
|
#define OSCONTAINER_CACHE_TIMEOUT (NANOSECS_PER_SEC/50)
|
||||||
|
|
||||||
class OSContainer: AllStatic {
|
class OSContainer: AllStatic {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _is_initialized;
|
static bool _is_initialized;
|
||||||
static bool _is_containerized;
|
static bool _is_containerized;
|
||||||
|
static int _active_processor_count;
|
||||||
|
|
||||||
static jlong read_memory_limit_in_bytes();
|
static jlong read_memory_limit_in_bytes();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user