1 /*
   2  * Copyright (c) 2003, 2010, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 # include "incls/_precompiled.incl"
  26 # include "incls/_runtimeService.cpp.incl"
  27 
  28 HS_DTRACE_PROBE_DECL(hs_private, safepoint__begin);
  29 HS_DTRACE_PROBE_DECL(hs_private, safepoint__end);
  30 
  31 TimeStamp RuntimeService::_app_timer;
  32 TimeStamp RuntimeService::_safepoint_timer;
  33 PerfCounter*  RuntimeService::_sync_time_ticks = NULL;
  34 PerfCounter*  RuntimeService::_total_safepoints = NULL;
  35 PerfCounter*  RuntimeService::_safepoint_time_ticks = NULL;
  36 PerfCounter*  RuntimeService::_application_time_ticks = NULL;
  37 PerfCounter*  RuntimeService::_thread_interrupt_signaled_count = NULL;
  38 PerfCounter*  RuntimeService::_interrupted_before_count = NULL;
  39 PerfCounter*  RuntimeService::_interrupted_during_count = NULL;
  40 
  41 void RuntimeService::init() {
  42   // Make sure the VM version is initialized
  43   Abstract_VM_Version::initialize();
  44 
  45   if (UsePerfData) {
  46     EXCEPTION_MARK;
  47 
  48     _sync_time_ticks =
  49               PerfDataManager::create_counter(SUN_RT, "safepointSyncTime",
  50                                               PerfData::U_Ticks, CHECK);
  51 
  52     _total_safepoints =
  53               PerfDataManager::create_counter(SUN_RT, "safepoints",
  54                                               PerfData::U_Events, CHECK);
  55 
  56     _safepoint_time_ticks =
  57               PerfDataManager::create_counter(SUN_RT, "safepointTime",
  58                                               PerfData::U_Ticks, CHECK);
  59 
  60     _application_time_ticks =
  61               PerfDataManager::create_counter(SUN_RT, "applicationTime",
  62                                               PerfData::U_Ticks, CHECK);
  63 
  64 
  65     // create performance counters for jvm_version and its capabilities
  66     PerfDataManager::create_constant(SUN_RT, "jvmVersion", PerfData::U_None,
  67                                      (jlong) Abstract_VM_Version::jvm_version(), CHECK);
  68 
  69     // I/O interruption related counters
  70 
  71     // thread signaling via os::interrupt()
  72 
  73     _thread_interrupt_signaled_count =
  74                 PerfDataManager::create_counter(SUN_RT,
  75                  "threadInterruptSignaled", PerfData::U_Events, CHECK);
  76 
  77     // OS_INTRPT via "check before" in _INTERRUPTIBLE
  78 
  79     _interrupted_before_count =
  80                 PerfDataManager::create_counter(SUN_RT, "interruptedBeforeIO",
  81                                                 PerfData::U_Events, CHECK);
  82 
  83     // OS_INTRPT via "check during" in _INTERRUPTIBLE
  84 
  85     _interrupted_during_count =
  86                 PerfDataManager::create_counter(SUN_RT, "interruptedDuringIO",
  87                                                 PerfData::U_Events, CHECK);
  88 
  89     // The capabilities counter is a binary representation of the VM capabilities in string.
  90     // This string respresentation simplifies the implementation of the client side
  91     // to parse the value.
  92     char capabilities[65];
  93     size_t len = sizeof(capabilities);
  94     memset((void*) capabilities, '0', len);
  95     capabilities[len-1] = '\0';
  96     capabilities[0] = AttachListener::is_attach_supported() ? '1' : '0';
  97 #ifdef KERNEL
  98     capabilities[1] = '1';
  99 #endif // KERNEL
 100     PerfDataManager::create_string_constant(SUN_RT, "jvmCapabilities",
 101                                             capabilities, CHECK);
 102   }
 103 }
 104 
 105 void RuntimeService::record_safepoint_begin() {
 106   HS_DTRACE_PROBE(hs_private, safepoint__begin);
 107 
 108   // Print the time interval in which the app was executing
 109   if (PrintGCApplicationConcurrentTime) {
 110     gclog_or_tty->print_cr("Application time: %3.7f seconds",
 111                                 last_application_time_sec());
 112   }
 113 
 114   // update the time stamp to begin recording safepoint time
 115   _safepoint_timer.update();
 116   if (UsePerfData) {
 117     _total_safepoints->inc();
 118     if (_app_timer.is_updated()) {
 119       _application_time_ticks->inc(_app_timer.ticks_since_update());
 120     }
 121   }
 122 }
 123 
 124 void RuntimeService::record_safepoint_synchronized() {
 125   if (UsePerfData) {
 126     _sync_time_ticks->inc(_safepoint_timer.ticks_since_update());
 127   }
 128 }
 129 
 130 void RuntimeService::record_safepoint_end() {
 131   HS_DTRACE_PROBE(hs_private, safepoint__end);
 132 
 133   // Print the time interval for which the app was stopped
 134   // during the current safepoint operation.
 135   if (PrintGCApplicationStoppedTime) {
 136     gclog_or_tty->print_cr("Total time for which application threads "
 137                            "were stopped: %3.7f seconds",
 138                            last_safepoint_time_sec());
 139   }
 140 
 141   // update the time stamp to begin recording app time
 142   _app_timer.update();
 143   if (UsePerfData) {
 144     _safepoint_time_ticks->inc(_safepoint_timer.ticks_since_update());
 145   }
 146 }
 147 
 148 void RuntimeService::record_application_start() {
 149   // update the time stamp to begin recording app time
 150   _app_timer.update();
 151 }
 152 
 153 // Don't need to record application end because we currently
 154 // exit at a safepoint and record_safepoint_begin() handles updating
 155 // the application time counter at VM exit.
 156 
 157 jlong RuntimeService::safepoint_sync_time_ms() {
 158   return UsePerfData ?
 159     Management::ticks_to_ms(_sync_time_ticks->get_value()) : -1;
 160 }
 161 
 162 jlong RuntimeService::safepoint_count() {
 163   return UsePerfData ?
 164     _total_safepoints->get_value() : -1;
 165 }
 166 jlong RuntimeService::safepoint_time_ms() {
 167   return UsePerfData ?
 168     Management::ticks_to_ms(_safepoint_time_ticks->get_value()) : -1;
 169 }
 170 
 171 jlong RuntimeService::application_time_ms() {
 172   return UsePerfData ?
 173     Management::ticks_to_ms(_application_time_ticks->get_value()) : -1;
 174 }
 175 
 176 void RuntimeService::record_interrupted_before_count() {
 177   if (UsePerfData) {
 178     _interrupted_before_count->inc();
 179   }
 180 }
 181 
 182 void RuntimeService::record_interrupted_during_count() {
 183   if (UsePerfData) {
 184     _interrupted_during_count->inc();
 185   }
 186 }
 187 
 188 void RuntimeService::record_thread_interrupt_signaled_count() {
 189   if (UsePerfData) {
 190     _thread_interrupt_signaled_count->inc();
 191   }
 192 }