1 /* 2 * Copyright (c) 1997, 2014, 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 "precompiled.hpp" 26 #include "oops/oop.inline.hpp" 27 #include "runtime/timer.hpp" 28 #include "utilities/ostream.hpp" 29 30 double TimeHelper::counter_to_seconds(jlong counter) { 31 double freq = (double) os::elapsed_frequency(); 32 return counter / freq; 33 } 34 35 double TimeHelper::counter_to_millis(jlong counter) { 36 return counter_to_seconds(counter) * 1000.0; 37 } 38 39 void elapsedTimer::add(elapsedTimer t) { 40 _counter += t._counter; 41 } 42 43 void elapsedTimer::start() { 44 if (!_active) { 45 _active = true; 46 _start_counter = os::elapsed_counter(); 47 } 48 } 49 50 void elapsedTimer::stop() { 51 if (_active) { 52 _counter += os::elapsed_counter() - _start_counter; 53 _active = false; 54 } 55 } 56 57 double elapsedTimer::seconds() const { 58 return TimeHelper::counter_to_seconds(_counter); 59 } 60 61 jlong elapsedTimer::milliseconds() const { 62 return TimeHelper::counter_to_millis(_counter); 63 } 64 65 jlong elapsedTimer::active_ticks() const { 66 if (!_active) { 67 return ticks(); 68 } 69 jlong counter = _counter + os::elapsed_counter() - _start_counter; 70 return counter; 71 } 72 73 void TimeStamp::update_to(jlong ticks) { 74 _counter = ticks; 75 if (_counter == 0) _counter = 1; 76 assert(is_updated(), "must not look clear"); 77 } 78 79 void TimeStamp::update() { 80 update_to(os::elapsed_counter()); 81 } 82 83 double TimeStamp::seconds() const { 84 assert(is_updated(), "must not be clear"); 85 jlong new_count = os::elapsed_counter(); 86 return TimeHelper::counter_to_seconds(new_count - _counter); 87 } 88 89 jlong TimeStamp::milliseconds() const { 90 assert(is_updated(), "must not be clear"); 91 jlong new_count = os::elapsed_counter(); 92 return TimeHelper::counter_to_millis(new_count - _counter); 93 } 94 95 jlong TimeStamp::ticks_since_update() const { 96 assert(is_updated(), "must not be clear"); 97 return os::elapsed_counter() - _counter; 98 } 99 100 TraceTime::TraceTime(const char* title, 101 bool doit) { 102 _active = doit; 103 _verbose = true; 104 105 if (_active) { 106 _accum = NULL; 107 tty->stamp(PrintGCTimeStamps); 108 tty->print("[%s", title); 109 tty->flush(); 110 _t.start(); 111 } 112 } 113 114 TraceTime::TraceTime(const char* title, 115 elapsedTimer* accumulator, 116 bool doit, 117 bool verbose) { 118 _active = doit; 119 _verbose = verbose; 120 if (_active) { 121 if (_verbose) { 122 tty->stamp(PrintGCTimeStamps); 123 tty->print("[%s", title); 124 tty->flush(); 125 } 126 _accum = accumulator; 127 _t.start(); 128 } 129 } 130 131 TraceTime::~TraceTime() { 132 if (_active) { 133 _t.stop(); 134 if (_accum!=NULL) _accum->add(_t); 135 if (_verbose) { 136 tty->print_cr(", %3.7f secs]", _t.seconds()); 137 tty->flush(); 138 } 139 } 140 } 141 142 TraceCPUTime::TraceCPUTime(bool doit, 143 bool print_cr, 144 outputStream *logfile) : 145 _active(doit), 146 _print_cr(print_cr), 147 _starting_user_time(0.0), 148 _starting_system_time(0.0), 149 _starting_real_time(0.0), 150 _logfile(logfile), 151 _error(false) { 152 if (_active) { 153 if (logfile != NULL) { 154 _logfile = logfile; 155 } else { 156 _logfile = tty; 157 } 158 159 _error = !os::getTimesSecs(&_starting_real_time, 160 &_starting_user_time, 161 &_starting_system_time); 162 } 163 } 164 165 TraceCPUTime::~TraceCPUTime() { 166 if (_active) { 167 bool valid = false; 168 if (!_error) { 169 double real_secs; // walk clock time 170 double system_secs; // system time 171 double user_secs; // user time for all threads 172 173 double real_time, user_time, system_time; 174 valid = os::getTimesSecs(&real_time, &user_time, &system_time); 175 if (valid) { 176 177 user_secs = user_time - _starting_user_time; 178 system_secs = system_time - _starting_system_time; 179 real_secs = real_time - _starting_real_time; 180 181 _logfile->print(" [Times: user=%3.2f sys=%3.2f real=%3.2f secs] ", 182 user_secs, system_secs, real_secs); 183 184 } else { 185 _logfile->print("[Invalid result in TraceCPUTime]"); 186 } 187 } else { 188 _logfile->print("[Error in TraceCPUTime]"); 189 } 190 if (_print_cr) { 191 _logfile->cr(); 192 } 193 _logfile->flush(); 194 } 195 }