From 0a12382dd21b8e1915fc57c67f7bb8b60ec2e944 Mon Sep 17 00:00:00 2001 From: Gengchen Tuo Date: Fri, 10 Nov 2023 11:09:32 -0500 Subject: [PATCH] Add a flag to return 0 if only one data point has been recorded Currently, getProcessCpuLoad() and getSystemCpuLoad() return -1 if only one data point has been recorded. A compatibility flag -XX:[+/-]CpuLoadCompatibility is added to match the behaviour of the RI, which is to return 0. Fixes: https://github.com/eclipse-openj9/openj9/issues/13389 Related: https://github.com/eclipse/omr/pull/7189 Signed-off-by: Gengchen Tuo --- .../ExtendedOperatingSystemMXBeanImpl.java | 17 ++++++++++++++--- runtime/jcl/common/extendedosmbean.c | 14 ++++++++++++++ runtime/jcl/common/mgmtosext.c | 8 ++++++++ runtime/jcl/exports.cmake | 1 + runtime/jcl/uma/se7_exports.xml | 1 + runtime/oti/j9consts.h | 2 +- runtime/oti/jclprots.h | 2 ++ runtime/oti/jvminit.h | 2 ++ runtime/vm/jvminit.c | 8 ++++++++ 9 files changed, 51 insertions(+), 4 deletions(-) diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/ExtendedOperatingSystemMXBeanImpl.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/ExtendedOperatingSystemMXBeanImpl.java index 6cf1a32adfe..d29a9d67934 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/ExtendedOperatingSystemMXBeanImpl.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/ExtendedOperatingSystemMXBeanImpl.java @@ -245,6 +245,12 @@ public final String getHardwareModel() throws UnsupportedOperationException { /* Returns the number of CPU's online at this very moment. */ private native int getOnlineProcessorsImpl(); + /** + * Check if the CpuLoadCompatibility flag is set. + * @return if the CpuLoadCompatibility flag is set + */ + private static native boolean hasCpuLoadCompatibilityFlag(); + /** * {@inheritDoc} */ @@ -263,8 +269,9 @@ public final synchronized double getProcessCpuLoad() { } latestCpuTime = cpuTime; - /* First call to this method should -1, since we don't have any previous - * CPU times (or timestamp) to compute CPU load against. + /* First call to this method returns 0 to match the behaviour of the RI. + * If the CpuLoadCompatibility flag is set, the bahaviour is reverted to + * return -1 for compatibility. */ if (-1 == oldTime) { /* Save current counters; next invocation onwards, we use these to @@ -272,7 +279,11 @@ public final synchronized double getProcessCpuLoad() { */ oldTime = interimTime = latestTime; oldCpuTime = interimCpuTime = latestCpuTime; - return CpuLoadCalculationConstants.ERROR_VALUE; + if (hasCpuLoadCompatibilityFlag()) { + return 0; + } else { + return CpuLoadCalculationConstants.ERROR_VALUE; + } } /* If a sufficiently long interval has elapsed since last sampling, calculate using diff --git a/runtime/jcl/common/extendedosmbean.c b/runtime/jcl/common/extendedosmbean.c index 66c88379428..590c3eeadd2 100644 --- a/runtime/jcl/common/extendedosmbean.c +++ b/runtime/jcl/common/extendedosmbean.c @@ -518,6 +518,20 @@ Java_com_ibm_lang_management_internal_ExtendedOperatingSystemMXBeanImpl_getHardw return (NULL == str) ? NULL : (*env)->NewStringUTF(env, str); } +/** + * Check if the CpuLoadCompatibility flag is set. + * + * @param env instance of JNIEnv + * @param unusedClass + * + * @return if the CpuLoadCompatibility flag is set + */ +jboolean JNICALL +Java_com_ibm_lang_management_internal_ExtendedOperatingSystemMXBeanImpl_hasCpuLoadCompatibilityFlag(JNIEnv *env, jclass unusedClass) { + J9JavaVM *vm = ((J9VMThread *)env)->javaVM; + return J9_ARE_ALL_BITS_SET(vm->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_CPU_LOAD_COMPATIBILITY); +} + /** * Returns the maximum number of file descriptors that can be opened in a process. * diff --git a/runtime/jcl/common/mgmtosext.c b/runtime/jcl/common/mgmtosext.c index 15cb77a373a..b516311ce88 100644 --- a/runtime/jcl/common/mgmtosext.c +++ b/runtime/jcl/common/mgmtosext.c @@ -83,6 +83,8 @@ jdouble JNICALL Java_com_ibm_lang_management_internal_ExtendedOperatingSystemMXBeanImpl_getSystemCpuLoadImpl(JNIEnv *env, jobject instance) { PORT_ACCESS_FROM_ENV(env); OMRPORT_ACCESS_FROM_J9PORT(PORTLIB); + + J9JavaVM *vm = ((J9VMThread *)env)->javaVM; double cpuLoad = 0.0; intptr_t portLibraryStatus = omrsysinfo_get_CPU_load(&cpuLoad); @@ -95,6 +97,12 @@ Java_com_ibm_lang_management_internal_ExtendedOperatingSystemMXBeanImpl_getSyste case OMRPORT_ERROR_SYSINFO_NOT_SUPPORTED: portLibraryStatus = -3; break; + case OMRPORT_ERROR_INSUFFICIENT_DATA: + portLibraryStatus = + J9_ARE_ALL_BITS_SET(vm->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_CPU_LOAD_COMPATIBILITY) + ? 0 + : -1; + break; default: portLibraryStatus = OMRPORT_ERROR_OPFAILED; break; diff --git a/runtime/jcl/exports.cmake b/runtime/jcl/exports.cmake index eb59fcd4fbc..58cb872e8a2 100644 --- a/runtime/jcl/exports.cmake +++ b/runtime/jcl/exports.cmake @@ -228,6 +228,7 @@ omr_add_exports(jclse Java_com_ibm_lang_management_internal_ExtendedOperatingSystemMXBeanImpl_getSystemCpuLoadImpl Java_com_ibm_lang_management_internal_ExtendedOperatingSystemMXBeanImpl_getTotalPhysicalMemoryImpl Java_com_ibm_lang_management_internal_ExtendedOperatingSystemMXBeanImpl_getTotalProcessorUsageImpl + Java_com_ibm_lang_management_internal_ExtendedOperatingSystemMXBeanImpl_hasCpuLoadCompatibilityFlag Java_com_ibm_lang_management_internal_ExtendedOperatingSystemMXBeanImpl_isDLPAREnabled Java_com_ibm_lang_management_internal_ExtendedRuntimeMXBeanImpl_getVMIdleStateImpl Java_com_ibm_lang_management_internal_JvmCpuMonitor_getThreadCategoryImpl diff --git a/runtime/jcl/uma/se7_exports.xml b/runtime/jcl/uma/se7_exports.xml index 25289847126..d62abf443f7 100644 --- a/runtime/jcl/uma/se7_exports.xml +++ b/runtime/jcl/uma/se7_exports.xml @@ -67,6 +67,7 @@ + diff --git a/runtime/oti/j9consts.h b/runtime/oti/j9consts.h index 440c7a81902..c41db8a2b25 100644 --- a/runtime/oti/j9consts.h +++ b/runtime/oti/j9consts.h @@ -361,7 +361,7 @@ extern "C" { #define J9_EXTENDED_RUNTIME2_USE_CONTAINER_SUPPORT 0x200000 #define J9_EXTENDED_RUNTIME2_SHOW_CARRIER_FRAMES 0x400000 #define J9_EXTENDED_RUNTIME2_CRIU_SINGLE_THROW_BLOCKING_EXCEPTIONS 0x800000 -#define J9_EXTENDED_RUNTIME2_UNUSED_0x1000000 0x1000000 +#define J9_EXTENDED_RUNTIME2_CPU_LOAD_COMPATIBILITY 0x1000000 #define J9_OBJECT_HEADER_AGE_DEFAULT 0xA /* OBJECT_HEADER_AGE_DEFAULT */ #define J9_OBJECT_HEADER_SHAPE_MASK 0xE /* OBJECT_HEADER_SHAPE_MASK */ diff --git a/runtime/oti/jclprots.h b/runtime/oti/jclprots.h index 1fcc2f7908f..ff6c91cbe3d 100644 --- a/runtime/oti/jclprots.h +++ b/runtime/oti/jclprots.h @@ -1166,6 +1166,8 @@ Java_com_ibm_lang_management_internal_ExtendedOperatingSystemMXBeanImpl_getOnlin jstring JNICALL Java_com_ibm_lang_management_internal_ExtendedOperatingSystemMXBeanImpl_getHardwareModelImpl(JNIEnv *env, jobject obj); +jboolean JNICALL +Java_com_ibm_lang_management_internal_ExtendedOperatingSystemMXBeanImpl_hasCpuLoadCompatibilityFlag(JNIEnv *env, jclass unusedClass); /** * Returns the maximum number of file descriptors that can be opened in a process. * diff --git a/runtime/oti/jvminit.h b/runtime/oti/jvminit.h index 5bfa34eb4e6..1539d0382f2 100644 --- a/runtime/oti/jvminit.h +++ b/runtime/oti/jvminit.h @@ -417,6 +417,8 @@ enum INIT_STAGE { #define VMOPT_XXDISABLEENSUREHASHED "-XX:-EnsureHashed:" #define VMOPT_XXOPENJ9COMMANDLINEENV "-XX:+OpenJ9CommandLineEnv" #define VMOPT_XXNOOPENJ9COMMANDLINEENV "-XX:-OpenJ9CommandLineEnv" +#define VMOPT_XXCPULOADCOMPATIBILITY "-XX:+CpuLoadCompatibility" +#define VMOPT_XXNOCPULOADCOMPATIBILITY "-XX:-CpuLoadCompatibility" #if defined(J9VM_ZOS_3164_INTEROPERABILITY) #define VMOPT_XXENABLE3164INTEROPERABILITY "-XX:+Enable3164Interoperability" diff --git a/runtime/vm/jvminit.c b/runtime/vm/jvminit.c index 0ee2c617a45..da347ec9e2d 100644 --- a/runtime/vm/jvminit.c +++ b/runtime/vm/jvminit.c @@ -4123,6 +4123,14 @@ processVMArgsFromFirstToLast(J9JavaVM * vm) } } + { + IDATA cpuLoadCompatibility = FIND_AND_CONSUME_VMARG(EXACT_MATCH, VMOPT_XXCPULOADCOMPATIBILITY , NULL); + IDATA noCpuLoadCompatibility = FIND_AND_CONSUME_VMARG(EXACT_MATCH, VMOPT_XXNOCPULOADCOMPATIBILITY , NULL); + if (cpuLoadCompatibility > noCpuLoadCompatibility) { + vm->extendedRuntimeFlags2 |= J9_EXTENDED_RUNTIME2_CPU_LOAD_COMPATIBILITY; + } + } + return JNI_OK; }