| /* | |
| * Copyright (c) 2011, 2025, Oracle and/or its affiliates. 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 | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. Oracle designates this | |
| * particular file as subject to the "Classpath" exception as provided | |
| * by Oracle in the LICENSE file that accompanied this code. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| #include "com_sun_management_internal_OperatingSystemImpl.h" | |
| #include <sys/time.h> | |
| #include <mach/mach.h> | |
| #include <mach/task_info.h> | |
| #include "jvm.h" | |
| JNIEXPORT jdouble JNICALL | |
| Java_com_sun_management_internal_OperatingSystemImpl_getCpuLoad0 | |
| (JNIEnv *env, jobject dummy) | |
| { | |
| // This code is influenced by the darwin top source | |
| kern_return_t kr; | |
| mach_msg_type_number_t count; | |
| host_cpu_load_info_data_t load; | |
| static jlong last_used = 0; | |
| static jlong last_total = 0; | |
| count = HOST_CPU_LOAD_INFO_COUNT; | |
| kr = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&load, &count); | |
| if (kr != KERN_SUCCESS) { | |
| return -1; | |
| } | |
| jlong used = load.cpu_ticks[CPU_STATE_USER] + load.cpu_ticks[CPU_STATE_NICE] + load.cpu_ticks[CPU_STATE_SYSTEM]; | |
| jlong total = used + load.cpu_ticks[CPU_STATE_IDLE]; | |
| if (last_used == 0 || last_total == 0) { | |
| // First call, just set the last values | |
| last_used = used; | |
| last_total = total; | |
| // return 0 since we have no data, not -1 which indicates error | |
| return 0; | |
| } | |
| jlong used_delta = used - last_used; | |
| jlong total_delta = total - last_total; | |
| if (total_delta == 0) { | |
| return 0; | |
| } | |
| jdouble cpu = (jdouble) used_delta / total_delta; | |
| last_used = used; | |
| last_total = total; | |
| return cpu; | |
| } | |
| #define TIME_VALUE_TO_TIMEVAL(a, r) do { \ | |
| (r)->tv_sec = (a)->seconds; \ | |
| (r)->tv_usec = (a)->microseconds; \ | |
| } while (0) | |
| #define TIME_VALUE_TO_MICROSECONDS(TV) \ | |
| ((TV).tv_sec * 1000 * 1000 + (TV).tv_usec) | |
| JNIEXPORT jdouble JNICALL | |
| Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0 | |
| (JNIEnv *env, jobject dummy) | |
| { | |
| // This code is influenced by the darwin top source | |
| struct task_basic_info_64 task_info_data; | |
| struct task_thread_times_info thread_info_data; | |
| struct timeval user_timeval, system_timeval, task_timeval; | |
| struct timeval now; | |
| mach_port_t task = mach_task_self(); | |
| kern_return_t kr; | |
| static jlong last_task_time = 0; | |
| static jlong last_time = 0; | |
| mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT; | |
| kr = task_info(task, | |
| TASK_THREAD_TIMES_INFO, | |
| (task_info_t)&thread_info_data, | |
| &thread_info_count); | |
| if (kr != KERN_SUCCESS) { | |
| // Most likely cause: |task| is a zombie. | |
| return -1; | |
| } | |
| mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT; | |
| kr = task_info(task, | |
| TASK_BASIC_INFO_64, | |
| (task_info_t)&task_info_data, | |
| &count); | |
| if (kr != KERN_SUCCESS) { | |
| // Most likely cause: |task| is a zombie. | |
| return -1; | |
| } | |
| /* Set total_time. */ | |
| // thread info contains live time... | |
| TIME_VALUE_TO_TIMEVAL(&thread_info_data.user_time, &user_timeval); | |
| TIME_VALUE_TO_TIMEVAL(&thread_info_data.system_time, &system_timeval); | |
| timeradd(&user_timeval, &system_timeval, &task_timeval); | |
| // ... task info contains terminated time. | |
| TIME_VALUE_TO_TIMEVAL(&task_info_data.user_time, &user_timeval); | |
| TIME_VALUE_TO_TIMEVAL(&task_info_data.system_time, &system_timeval); | |
| timeradd(&user_timeval, &task_timeval, &task_timeval); | |
| timeradd(&system_timeval, &task_timeval, &task_timeval); | |
| if (gettimeofday(&now, NULL) < 0) { | |
| return -1; | |
| } | |
| jint ncpus = JVM_ActiveProcessorCount(); | |
| jlong time = TIME_VALUE_TO_MICROSECONDS(now) * ncpus; | |
| jlong task_time = TIME_VALUE_TO_MICROSECONDS(task_timeval); | |
| if ((last_task_time == 0) || (last_time == 0)) { | |
| // First call, just set the last values. | |
| last_task_time = task_time; | |
| last_time = time; | |
| // return 0 since we have no data, not -1 which indicates error | |
| return 0; | |
| } | |
| jlong task_time_delta = task_time - last_task_time; | |
| jlong time_delta = time - last_time; | |
| if (time_delta == 0) { | |
| return -1; | |
| } | |
| jdouble cpu = (jdouble) task_time_delta / time_delta; | |
| last_task_time = task_time; | |
| last_time = time; | |
| return cpu; | |
| } | |
| JNIEXPORT jdouble JNICALL | |
| Java_com_sun_management_internal_OperatingSystemImpl_getSingleCpuLoad0 | |
| (JNIEnv *env, jobject dummy, jint cpu_number) | |
| { | |
| return -1.0; | |
| } | |
| JNIEXPORT jlong JNICALL | |
| Java_com_sun_management_internal_OperatingSystemImpl_getHostTotalCpuTicks0 | |
| (JNIEnv *env, jobject mbean) | |
| { | |
| return -1; | |
| } | |
| JNIEXPORT jint JNICALL | |
| Java_com_sun_management_internal_OperatingSystemImpl_getHostConfiguredCpuCount0 | |
| (JNIEnv *env, jobject mbean) | |
| { | |
| return -1; | |
| } | |
| JNIEXPORT jint JNICALL | |
| Java_com_sun_management_internal_OperatingSystemImpl_getHostOnlineCpuCount0 | |
| (JNIEnv *env, jobject mbean) | |
| { | |
| return -1; | |
| } | |