hotspot/src/share/vm/gc_implementation/shared/coTracker.cpp
changeset 3692 9530a85b334c
parent 3690 dba50b88bd50
parent 3691 c84b8483cd2c
child 3693 af387bf37e8d
equal deleted inserted replaced
3690:dba50b88bd50 3692:9530a85b334c
     1 /*
       
     2  * Copyright 2001-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  *
       
    23  */
       
    24 
       
    25 # include "incls/_precompiled.incl"
       
    26 # include "incls/_coTracker.cpp.incl"
       
    27 
       
    28 COTracker* COTracker::_head = NULL;
       
    29 double COTracker::_cpu_number = -1.0;
       
    30 
       
    31 void
       
    32 COTracker::resetPeriod(double now_sec, double vnow_sec) {
       
    33   guarantee( _enabled, "invariant" );
       
    34   _period_start_time_sec  = now_sec;
       
    35   _period_start_vtime_sec = vnow_sec;
       
    36 }
       
    37 
       
    38 void
       
    39 COTracker::setConcOverhead(double time_stamp_sec,
       
    40                            double conc_overhead) {
       
    41   guarantee( _enabled, "invariant" );
       
    42   _conc_overhead  = conc_overhead;
       
    43   _time_stamp_sec = time_stamp_sec;
       
    44   if (conc_overhead > 0.001)
       
    45     _conc_overhead_seq.add(conc_overhead);
       
    46 }
       
    47 
       
    48 void
       
    49 COTracker::reset(double starting_conc_overhead) {
       
    50   guarantee( _enabled, "invariant" );
       
    51   double now_sec = os::elapsedTime();
       
    52   setConcOverhead(now_sec, starting_conc_overhead);
       
    53 }
       
    54 
       
    55 void
       
    56 COTracker::start() {
       
    57   guarantee( _enabled, "invariant" );
       
    58   resetPeriod(os::elapsedTime(), os::elapsedVTime());
       
    59 }
       
    60 
       
    61 void
       
    62 COTracker::update(bool force_end) {
       
    63   assert( _enabled, "invariant" );
       
    64   double end_time_sec = os::elapsedTime();
       
    65   double elapsed_time_sec = end_time_sec - _period_start_time_sec;
       
    66   if (force_end || elapsed_time_sec > _update_period_sec) {
       
    67     // reached the end of the period
       
    68     double end_vtime_sec = os::elapsedVTime();
       
    69     double elapsed_vtime_sec = end_vtime_sec - _period_start_vtime_sec;
       
    70 
       
    71     double conc_overhead = elapsed_vtime_sec / elapsed_time_sec;
       
    72 
       
    73     setConcOverhead(end_time_sec, conc_overhead);
       
    74     resetPeriod(end_time_sec, end_vtime_sec);
       
    75   }
       
    76 }
       
    77 
       
    78 void
       
    79 COTracker::updateForSTW(double start_sec, double end_sec) {
       
    80   if (!_enabled)
       
    81     return;
       
    82 
       
    83   // During a STW pause, no concurrent GC thread has done any
       
    84   // work. So, we can safely adjust the start of the current period by
       
    85   // adding the duration of the STW pause to it, so that the STW pause
       
    86   // doesn't affect the reading of the concurrent overhead (it's
       
    87   // basically like excluding the time of the STW pause from the
       
    88   // concurrent overhead calculation).
       
    89 
       
    90   double stw_duration_sec = end_sec - start_sec;
       
    91   guarantee( stw_duration_sec > 0.0, "invariant" );
       
    92 
       
    93   if (outOfDate(start_sec))
       
    94     _conc_overhead = 0.0;
       
    95   else
       
    96     _time_stamp_sec = end_sec;
       
    97   _period_start_time_sec += stw_duration_sec;
       
    98   _conc_overhead_seq = NumberSeq();
       
    99 
       
   100   guarantee( os::elapsedTime() > _period_start_time_sec, "invariant" );
       
   101 }
       
   102 
       
   103 double
       
   104 COTracker::predConcOverhead() {
       
   105   if (_enabled) {
       
   106     // tty->print(" %1.2lf", _conc_overhead_seq.maximum());
       
   107     return _conc_overhead_seq.maximum();
       
   108   } else {
       
   109     // tty->print(" DD");
       
   110     return 0.0;
       
   111   }
       
   112 }
       
   113 
       
   114 void
       
   115 COTracker::resetPred() {
       
   116   _conc_overhead_seq = NumberSeq();
       
   117 }
       
   118 
       
   119 COTracker::COTracker(int group)
       
   120     : _enabled(false),
       
   121       _group(group),
       
   122       _period_start_time_sec(-1.0),
       
   123       _period_start_vtime_sec(-1.0),
       
   124       _conc_overhead(-1.0),
       
   125       _time_stamp_sec(-1.0),
       
   126       _next(NULL) {
       
   127   // GCOverheadReportingPeriodMS indicates how frequently the
       
   128   // concurrent overhead will be recorded by the GC Overhead
       
   129   // Reporter. We want to take readings less often than that. If we
       
   130   // took readings more often than some of them might be lost.
       
   131   _update_period_sec = ((double) GCOverheadReportingPeriodMS) / 1000.0 * 1.25;
       
   132   _next = _head;
       
   133   _head = this;
       
   134 
       
   135   if (_cpu_number < 0.0)
       
   136     _cpu_number = (double) os::processor_count();
       
   137 }
       
   138 
       
   139 // statics
       
   140 
       
   141 void
       
   142 COTracker::updateAllForSTW(double start_sec, double end_sec) {
       
   143   for (COTracker* curr = _head; curr != NULL; curr = curr->_next) {
       
   144     curr->updateForSTW(start_sec, end_sec);
       
   145   }
       
   146 }
       
   147 
       
   148 double
       
   149 COTracker::totalConcOverhead(double now_sec) {
       
   150   double total_conc_overhead = 0.0;
       
   151 
       
   152   for (COTracker* curr = _head; curr != NULL; curr = curr->_next) {
       
   153     double conc_overhead = curr->concOverhead(now_sec);
       
   154     total_conc_overhead += conc_overhead;
       
   155   }
       
   156 
       
   157   return total_conc_overhead;
       
   158 }
       
   159 
       
   160 double
       
   161 COTracker::totalConcOverhead(double now_sec,
       
   162                              size_t group_num,
       
   163                              double* co_per_group) {
       
   164   double total_conc_overhead = 0.0;
       
   165 
       
   166   for (size_t i = 0; i < group_num; ++i)
       
   167     co_per_group[i] = 0.0;
       
   168 
       
   169   for (COTracker* curr = _head; curr != NULL; curr = curr->_next) {
       
   170     size_t group = curr->_group;
       
   171     assert( 0 <= group && group < group_num, "invariant" );
       
   172     double conc_overhead = curr->concOverhead(now_sec);
       
   173 
       
   174     co_per_group[group] += conc_overhead;
       
   175     total_conc_overhead += conc_overhead;
       
   176   }
       
   177 
       
   178   return total_conc_overhead;
       
   179 }
       
   180 
       
   181 double
       
   182 COTracker::totalPredConcOverhead() {
       
   183   double total_pred_conc_overhead = 0.0;
       
   184   for (COTracker* curr = _head; curr != NULL; curr = curr->_next) {
       
   185     total_pred_conc_overhead += curr->predConcOverhead();
       
   186     curr->resetPred();
       
   187   }
       
   188   return total_pred_conc_overhead / _cpu_number;
       
   189 }