comparison src/share/vm/gc_implementation/shared/coTracker.cpp @ 342:37f87013dfd8

6711316: Open source the Garbage-First garbage collector Summary: First mercurial integration of the code for the Garbage-First garbage collector. Reviewed-by: apetrusenko, iveresov, jmasa, sgoldman, tonyp, ysr
author ysr
date Thu, 05 Jun 2008 15:57:56 -0700
parents
children
comparison
equal deleted inserted replaced
189:0b27f3512f9e 342:37f87013dfd8
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 }