jdk/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c
changeset 30355 e37c7eba132f
parent 25859 3317bb8137f4
equal deleted inserted replaced
30354:ca83b4cae363 30355:e37c7eba132f
       
     1 /*
       
     2  * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 #include "com_sun_management_internal_OperatingSystemImpl.h"
       
    27 
       
    28 #include <sys/time.h>
       
    29 #include <mach/mach.h>
       
    30 #include <mach/task_info.h>
       
    31 
       
    32 #include "jvm.h"
       
    33 
       
    34 JNIEXPORT jdouble JNICALL
       
    35 Java_com_sun_management_internal_OperatingSystemImpl_getSystemCpuLoad0
       
    36 (JNIEnv *env, jobject dummy)
       
    37 {
       
    38     // This code is influenced by the darwin top source
       
    39 
       
    40     kern_return_t kr;
       
    41     mach_msg_type_number_t count;
       
    42     host_cpu_load_info_data_t load;
       
    43 
       
    44     static jlong last_used  = 0;
       
    45     static jlong last_total = 0;
       
    46 
       
    47     count = HOST_CPU_LOAD_INFO_COUNT;
       
    48     kr = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&load, &count);
       
    49     if (kr != KERN_SUCCESS) {
       
    50         return -1;
       
    51     }
       
    52 
       
    53     jlong used  = load.cpu_ticks[CPU_STATE_USER] + load.cpu_ticks[CPU_STATE_NICE] + load.cpu_ticks[CPU_STATE_SYSTEM];
       
    54     jlong total = used + load.cpu_ticks[CPU_STATE_IDLE];
       
    55 
       
    56     if (last_used == 0 || last_total == 0) {
       
    57         // First call, just set the last values
       
    58         last_used  = used;
       
    59         last_total = total;
       
    60         // return 0 since we have no data, not -1 which indicates error
       
    61         return 0;
       
    62     }
       
    63 
       
    64     jlong used_delta  = used - last_used;
       
    65     jlong total_delta = total - last_total;
       
    66 
       
    67     jdouble cpu = (jdouble) used_delta / total_delta;
       
    68 
       
    69     last_used  = used;
       
    70     last_total = total;
       
    71 
       
    72     return cpu;
       
    73 }
       
    74 
       
    75 
       
    76 #define TIME_VALUE_TO_TIMEVAL(a, r) do {  \
       
    77      (r)->tv_sec = (a)->seconds;          \
       
    78      (r)->tv_usec = (a)->microseconds;    \
       
    79 } while (0)
       
    80 
       
    81 
       
    82 #define TIME_VALUE_TO_MICROSECONDS(TV) \
       
    83      ((TV).tv_sec * 1000 * 1000 + (TV).tv_usec)
       
    84 
       
    85 
       
    86 JNIEXPORT jdouble JNICALL
       
    87 Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0
       
    88 (JNIEnv *env, jobject dummy)
       
    89 {
       
    90     // This code is influenced by the darwin top source
       
    91 
       
    92     struct task_basic_info_64 task_info_data;
       
    93     struct task_thread_times_info thread_info_data;
       
    94     struct timeval user_timeval, system_timeval, task_timeval;
       
    95     struct timeval now;
       
    96     mach_port_t task = mach_task_self();
       
    97     kern_return_t kr;
       
    98 
       
    99     static jlong last_task_time = 0;
       
   100     static jlong last_time      = 0;
       
   101 
       
   102     mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT;
       
   103     kr = task_info(task,
       
   104             TASK_THREAD_TIMES_INFO,
       
   105             (task_info_t)&thread_info_data,
       
   106             &thread_info_count);
       
   107     if (kr != KERN_SUCCESS) {
       
   108         // Most likely cause: |task| is a zombie.
       
   109         return -1;
       
   110     }
       
   111 
       
   112     mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT;
       
   113     kr = task_info(task,
       
   114             TASK_BASIC_INFO_64,
       
   115             (task_info_t)&task_info_data,
       
   116             &count);
       
   117     if (kr != KERN_SUCCESS) {
       
   118         // Most likely cause: |task| is a zombie.
       
   119         return -1;
       
   120     }
       
   121 
       
   122     /* Set total_time. */
       
   123     // thread info contains live time...
       
   124     TIME_VALUE_TO_TIMEVAL(&thread_info_data.user_time, &user_timeval);
       
   125     TIME_VALUE_TO_TIMEVAL(&thread_info_data.system_time, &system_timeval);
       
   126     timeradd(&user_timeval, &system_timeval, &task_timeval);
       
   127 
       
   128     // ... task info contains terminated time.
       
   129     TIME_VALUE_TO_TIMEVAL(&task_info_data.user_time, &user_timeval);
       
   130     TIME_VALUE_TO_TIMEVAL(&task_info_data.system_time, &system_timeval);
       
   131     timeradd(&user_timeval, &task_timeval, &task_timeval);
       
   132     timeradd(&system_timeval, &task_timeval, &task_timeval);
       
   133 
       
   134     if (gettimeofday(&now, NULL) < 0) {
       
   135        return -1;
       
   136     }
       
   137     jint ncpus      = JVM_ActiveProcessorCount();
       
   138     jlong time      = TIME_VALUE_TO_MICROSECONDS(now) * ncpus;
       
   139     jlong task_time = TIME_VALUE_TO_MICROSECONDS(task_timeval);
       
   140 
       
   141     if ((last_task_time == 0) || (last_time == 0)) {
       
   142         // First call, just set the last values.
       
   143         last_task_time = task_time;
       
   144         last_time      = time;
       
   145         // return 0 since we have no data, not -1 which indicates error
       
   146         return 0;
       
   147     }
       
   148 
       
   149     jlong task_time_delta = task_time - last_task_time;
       
   150     jlong time_delta      = time - last_time;
       
   151     if (time_delta == 0) {
       
   152         return -1;
       
   153     }
       
   154 
       
   155     jdouble cpu = (jdouble) task_time_delta / time_delta;
       
   156 
       
   157     last_task_time = task_time;
       
   158     last_time      = time;
       
   159 
       
   160     return cpu;
       
   161  }