Sat, 27 Sep 2008 00:33:13 -0700
6740923: NUMA allocator: Ensure the progress of adaptive chunk resizing
Summary: Treat a chuck where the allocation has failed as fully used.
Reviewed-by: ysr
ysr@777 | 1 | /* |
ysr@777 | 2 | * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. |
ysr@777 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
ysr@777 | 4 | * |
ysr@777 | 5 | * This code is free software; you can redistribute it and/or modify it |
ysr@777 | 6 | * under the terms of the GNU General Public License version 2 only, as |
ysr@777 | 7 | * published by the Free Software Foundation. |
ysr@777 | 8 | * |
ysr@777 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
ysr@777 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
ysr@777 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
ysr@777 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
ysr@777 | 13 | * accompanied this code). |
ysr@777 | 14 | * |
ysr@777 | 15 | * You should have received a copy of the GNU General Public License version |
ysr@777 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
ysr@777 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
ysr@777 | 18 | * |
ysr@777 | 19 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
ysr@777 | 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
ysr@777 | 21 | * have any questions. |
ysr@777 | 22 | * |
ysr@777 | 23 | */ |
ysr@777 | 24 | |
ysr@777 | 25 | # include "incls/_precompiled.incl" |
ysr@777 | 26 | # include "incls/_coTracker.cpp.incl" |
ysr@777 | 27 | |
ysr@777 | 28 | COTracker* COTracker::_head = NULL; |
ysr@777 | 29 | double COTracker::_cpu_number = -1.0; |
ysr@777 | 30 | |
ysr@777 | 31 | void |
ysr@777 | 32 | COTracker::resetPeriod(double now_sec, double vnow_sec) { |
ysr@777 | 33 | guarantee( _enabled, "invariant" ); |
ysr@777 | 34 | _period_start_time_sec = now_sec; |
ysr@777 | 35 | _period_start_vtime_sec = vnow_sec; |
ysr@777 | 36 | } |
ysr@777 | 37 | |
ysr@777 | 38 | void |
ysr@777 | 39 | COTracker::setConcOverhead(double time_stamp_sec, |
ysr@777 | 40 | double conc_overhead) { |
ysr@777 | 41 | guarantee( _enabled, "invariant" ); |
ysr@777 | 42 | _conc_overhead = conc_overhead; |
ysr@777 | 43 | _time_stamp_sec = time_stamp_sec; |
ysr@777 | 44 | if (conc_overhead > 0.001) |
ysr@777 | 45 | _conc_overhead_seq.add(conc_overhead); |
ysr@777 | 46 | } |
ysr@777 | 47 | |
ysr@777 | 48 | void |
ysr@777 | 49 | COTracker::reset(double starting_conc_overhead) { |
ysr@777 | 50 | guarantee( _enabled, "invariant" ); |
ysr@777 | 51 | double now_sec = os::elapsedTime(); |
ysr@777 | 52 | setConcOverhead(now_sec, starting_conc_overhead); |
ysr@777 | 53 | } |
ysr@777 | 54 | |
ysr@777 | 55 | void |
ysr@777 | 56 | COTracker::start() { |
ysr@777 | 57 | guarantee( _enabled, "invariant" ); |
ysr@777 | 58 | resetPeriod(os::elapsedTime(), os::elapsedVTime()); |
ysr@777 | 59 | } |
ysr@777 | 60 | |
ysr@777 | 61 | void |
ysr@777 | 62 | COTracker::update(bool force_end) { |
ysr@777 | 63 | assert( _enabled, "invariant" ); |
ysr@777 | 64 | double end_time_sec = os::elapsedTime(); |
ysr@777 | 65 | double elapsed_time_sec = end_time_sec - _period_start_time_sec; |
ysr@777 | 66 | if (force_end || elapsed_time_sec > _update_period_sec) { |
ysr@777 | 67 | // reached the end of the period |
ysr@777 | 68 | double end_vtime_sec = os::elapsedVTime(); |
ysr@777 | 69 | double elapsed_vtime_sec = end_vtime_sec - _period_start_vtime_sec; |
ysr@777 | 70 | |
ysr@777 | 71 | double conc_overhead = elapsed_vtime_sec / elapsed_time_sec; |
ysr@777 | 72 | |
ysr@777 | 73 | setConcOverhead(end_time_sec, conc_overhead); |
ysr@777 | 74 | resetPeriod(end_time_sec, end_vtime_sec); |
ysr@777 | 75 | } |
ysr@777 | 76 | } |
ysr@777 | 77 | |
ysr@777 | 78 | void |
ysr@777 | 79 | COTracker::updateForSTW(double start_sec, double end_sec) { |
ysr@777 | 80 | if (!_enabled) |
ysr@777 | 81 | return; |
ysr@777 | 82 | |
ysr@777 | 83 | // During a STW pause, no concurrent GC thread has done any |
ysr@777 | 84 | // work. So, we can safely adjust the start of the current period by |
ysr@777 | 85 | // adding the duration of the STW pause to it, so that the STW pause |
ysr@777 | 86 | // doesn't affect the reading of the concurrent overhead (it's |
ysr@777 | 87 | // basically like excluding the time of the STW pause from the |
ysr@777 | 88 | // concurrent overhead calculation). |
ysr@777 | 89 | |
ysr@777 | 90 | double stw_duration_sec = end_sec - start_sec; |
ysr@777 | 91 | guarantee( stw_duration_sec > 0.0, "invariant" ); |
ysr@777 | 92 | |
ysr@777 | 93 | if (outOfDate(start_sec)) |
ysr@777 | 94 | _conc_overhead = 0.0; |
ysr@777 | 95 | else |
ysr@777 | 96 | _time_stamp_sec = end_sec; |
ysr@777 | 97 | _period_start_time_sec += stw_duration_sec; |
ysr@777 | 98 | _conc_overhead_seq = NumberSeq(); |
ysr@777 | 99 | |
ysr@777 | 100 | guarantee( os::elapsedTime() > _period_start_time_sec, "invariant" ); |
ysr@777 | 101 | } |
ysr@777 | 102 | |
ysr@777 | 103 | double |
ysr@777 | 104 | COTracker::predConcOverhead() { |
ysr@777 | 105 | if (_enabled) { |
ysr@777 | 106 | // tty->print(" %1.2lf", _conc_overhead_seq.maximum()); |
ysr@777 | 107 | return _conc_overhead_seq.maximum(); |
ysr@777 | 108 | } else { |
ysr@777 | 109 | // tty->print(" DD"); |
ysr@777 | 110 | return 0.0; |
ysr@777 | 111 | } |
ysr@777 | 112 | } |
ysr@777 | 113 | |
ysr@777 | 114 | void |
ysr@777 | 115 | COTracker::resetPred() { |
ysr@777 | 116 | _conc_overhead_seq = NumberSeq(); |
ysr@777 | 117 | } |
ysr@777 | 118 | |
ysr@777 | 119 | COTracker::COTracker(int group) |
ysr@777 | 120 | : _enabled(false), |
ysr@777 | 121 | _group(group), |
ysr@777 | 122 | _period_start_time_sec(-1.0), |
ysr@777 | 123 | _period_start_vtime_sec(-1.0), |
ysr@777 | 124 | _conc_overhead(-1.0), |
ysr@777 | 125 | _time_stamp_sec(-1.0), |
ysr@777 | 126 | _next(NULL) { |
ysr@777 | 127 | // GCOverheadReportingPeriodMS indicates how frequently the |
ysr@777 | 128 | // concurrent overhead will be recorded by the GC Overhead |
ysr@777 | 129 | // Reporter. We want to take readings less often than that. If we |
ysr@777 | 130 | // took readings more often than some of them might be lost. |
ysr@777 | 131 | _update_period_sec = ((double) GCOverheadReportingPeriodMS) / 1000.0 * 1.25; |
ysr@777 | 132 | _next = _head; |
ysr@777 | 133 | _head = this; |
ysr@777 | 134 | |
ysr@777 | 135 | if (_cpu_number < 0.0) |
ysr@777 | 136 | _cpu_number = (double) os::processor_count(); |
ysr@777 | 137 | } |
ysr@777 | 138 | |
ysr@777 | 139 | // statics |
ysr@777 | 140 | |
ysr@777 | 141 | void |
ysr@777 | 142 | COTracker::updateAllForSTW(double start_sec, double end_sec) { |
ysr@777 | 143 | for (COTracker* curr = _head; curr != NULL; curr = curr->_next) { |
ysr@777 | 144 | curr->updateForSTW(start_sec, end_sec); |
ysr@777 | 145 | } |
ysr@777 | 146 | } |
ysr@777 | 147 | |
ysr@777 | 148 | double |
ysr@777 | 149 | COTracker::totalConcOverhead(double now_sec) { |
ysr@777 | 150 | double total_conc_overhead = 0.0; |
ysr@777 | 151 | |
ysr@777 | 152 | for (COTracker* curr = _head; curr != NULL; curr = curr->_next) { |
ysr@777 | 153 | double conc_overhead = curr->concOverhead(now_sec); |
ysr@777 | 154 | total_conc_overhead += conc_overhead; |
ysr@777 | 155 | } |
ysr@777 | 156 | |
ysr@777 | 157 | return total_conc_overhead; |
ysr@777 | 158 | } |
ysr@777 | 159 | |
ysr@777 | 160 | double |
ysr@777 | 161 | COTracker::totalConcOverhead(double now_sec, |
ysr@777 | 162 | size_t group_num, |
ysr@777 | 163 | double* co_per_group) { |
ysr@777 | 164 | double total_conc_overhead = 0.0; |
ysr@777 | 165 | |
ysr@777 | 166 | for (size_t i = 0; i < group_num; ++i) |
ysr@777 | 167 | co_per_group[i] = 0.0; |
ysr@777 | 168 | |
ysr@777 | 169 | for (COTracker* curr = _head; curr != NULL; curr = curr->_next) { |
ysr@777 | 170 | size_t group = curr->_group; |
ysr@777 | 171 | assert( 0 <= group && group < group_num, "invariant" ); |
ysr@777 | 172 | double conc_overhead = curr->concOverhead(now_sec); |
ysr@777 | 173 | |
ysr@777 | 174 | co_per_group[group] += conc_overhead; |
ysr@777 | 175 | total_conc_overhead += conc_overhead; |
ysr@777 | 176 | } |
ysr@777 | 177 | |
ysr@777 | 178 | return total_conc_overhead; |
ysr@777 | 179 | } |
ysr@777 | 180 | |
ysr@777 | 181 | double |
ysr@777 | 182 | COTracker::totalPredConcOverhead() { |
ysr@777 | 183 | double total_pred_conc_overhead = 0.0; |
ysr@777 | 184 | for (COTracker* curr = _head; curr != NULL; curr = curr->_next) { |
ysr@777 | 185 | total_pred_conc_overhead += curr->predConcOverhead(); |
ysr@777 | 186 | curr->resetPred(); |
ysr@777 | 187 | } |
ysr@777 | 188 | return total_pred_conc_overhead / _cpu_number; |
ysr@777 | 189 | } |