diff --git a/src/jdk.management/aix/native/libmanagement_ext/UnixOperatingSystem.c b/src/jdk.management/aix/native/libmanagement_ext/UnixOperatingSystem.c index 228c5eb5c14e6..c9888fec52af5 100644 --- a/src/jdk.management/aix/native/libmanagement_ext/UnixOperatingSystem.c +++ b/src/jdk.management/aix/native/libmanagement_ext/UnixOperatingSystem.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2015, 2020 SAP SE. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,20 +28,93 @@ /* Implement and update https://bugs.openjdk.org/browse/JDK-8030957 */ #include +#include +#include +#include #include "com_sun_management_internal_OperatingSystemImpl.h" +perfstat_process_t prev_stats = {0}; +static unsigned long long prev_timebase = 0; +static int initialized = 0; +#define HTIC2SEC(x) (((double)(x) * XINTFRAC) / 1000000000.0) + +static perfstat_cpu_total_t cpu_total_old; +static time_t last_sample_time = 0; +static double last_cpu_load = -1.0; JNIEXPORT jdouble JNICALL Java_com_sun_management_internal_OperatingSystemImpl_getCpuLoad0 (JNIEnv *env, jobject dummy) { - return -1.0; + perfstat_cpu_total_t cpu_total; + int ret; + + time_t now = time(NULL); + if (initialized && (now - last_sample_time < 5)) { + return last_cpu_load; // Return cached value if less than 5s + } + + ret = perfstat_cpu_total(NULL, &cpu_total, sizeof(perfstat_cpu_total_t), 1); + if (ret < 0) { + return -1.0; + } + + if (!initialized) { + cpu_total_old = cpu_total; + initialized = 1; + last_sample_time = now; + return -1.0; + } + + long long user_diff = cpu_total.user - cpu_total_old.user; + long long sys_diff = cpu_total.sys - cpu_total_old.sys; + long long idle_diff = cpu_total.idle - cpu_total_old.idle; + long long wait_diff = cpu_total.wait - cpu_total_old.wait; + long long total = user_diff + sys_diff + idle_diff + wait_diff; + + if (total == 0) { + return -1.0; + } + + double load = (double)(user_diff + sys_diff) / total; + fflush(stdout); + last_cpu_load = load; + last_sample_time = now; + cpu_total_old = cpu_total; + + return load; } JNIEXPORT jdouble JNICALL Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0 (JNIEnv *env, jobject dummy) { - return -1.0; + perfstat_process_t curr_stats; + perfstat_id_t id; + unsigned long long curr_timebase, timebase_diff; + double user_diff, sys_diff, delta_time; + + if (perfstat_process(&id, &curr_stats, sizeof(perfstat_process_t), 1) < 0) { + return -1.0; + } + if (!initialized) { + prev_stats = curr_stats; + prev_timebase = curr_stats.last_timebase; + initialized = 1; + return -1.0; + } + curr_timebase = curr_stats.last_timebase; + timebase_diff = curr_timebase - prev_timebase; + if ((long long)timebase_diff <= 0 || XINTFRAC == 0) { + return -1.0; + } + + delta_time = HTIC2SEC(timebase_diff); + user_diff = (double)(curr_stats.ucpu_time - prev_stats.ucpu_time); + sys_diff = (double)(curr_stats.scpu_time - prev_stats.scpu_time); + prev_stats = curr_stats; + prev_timebase = curr_timebase; + double cpu_load = (user_diff + sys_diff) / delta_time; + return (jdouble)cpu_load; } JNIEXPORT jdouble JNICALL diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index b84c38021e92d..0e29c8ba32d1d 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -553,8 +553,6 @@ java/io/IO/IO.java 8337935 linux-pp # jdk_management -com/sun/management/OperatingSystemMXBean/GetProcessCpuLoad.java 8030957 aix-all -com/sun/management/OperatingSystemMXBean/GetSystemCpuLoad.java 8030957 aix-all java/lang/management/MemoryMXBean/Pending.java 8158837 generic-all java/lang/management/MemoryMXBean/PendingAllGC.sh 8158837 generic-all