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/_gcOverheadReporter.cpp.incl" |
ysr@777 | 27 | |
ysr@777 | 28 | class COReportingThread : public ConcurrentGCThread { |
ysr@777 | 29 | private: |
ysr@777 | 30 | GCOverheadReporter* _reporter; |
ysr@777 | 31 | |
ysr@777 | 32 | public: |
ysr@777 | 33 | COReportingThread(GCOverheadReporter* reporter) : _reporter(reporter) { |
ysr@777 | 34 | guarantee( _reporter != NULL, "precondition" ); |
ysr@777 | 35 | create_and_start(); |
ysr@777 | 36 | } |
ysr@777 | 37 | |
ysr@777 | 38 | virtual void run() { |
ysr@777 | 39 | initialize_in_thread(); |
ysr@777 | 40 | wait_for_universe_init(); |
ysr@777 | 41 | |
ysr@777 | 42 | int period_ms = GCOverheadReportingPeriodMS; |
ysr@777 | 43 | |
ysr@777 | 44 | while ( true ) { |
ysr@777 | 45 | os::sleep(Thread::current(), period_ms, false); |
ysr@777 | 46 | |
ysr@777 | 47 | _sts.join(); |
ysr@777 | 48 | double now_sec = os::elapsedTime(); |
ysr@777 | 49 | _reporter->collect_and_record_conc_overhead(now_sec); |
ysr@777 | 50 | _sts.leave(); |
ysr@777 | 51 | } |
ysr@777 | 52 | |
ysr@777 | 53 | terminate(); |
ysr@777 | 54 | } |
ysr@777 | 55 | }; |
ysr@777 | 56 | |
ysr@777 | 57 | GCOverheadReporter* GCOverheadReporter::_reporter = NULL; |
ysr@777 | 58 | |
ysr@777 | 59 | GCOverheadReporter::GCOverheadReporter(size_t group_num, |
ysr@777 | 60 | const char* group_names[], |
ysr@777 | 61 | size_t length) |
ysr@777 | 62 | : _group_num(group_num), _prev_end_sec(0.0) { |
ysr@777 | 63 | guarantee( 0 <= group_num && group_num <= MaxGCOverheadGroupNum, |
ysr@777 | 64 | "precondition" ); |
ysr@777 | 65 | |
ysr@777 | 66 | _base = NEW_C_HEAP_ARRAY(GCOverheadReporterEntry, length); |
ysr@777 | 67 | _top = _base + length; |
ysr@777 | 68 | _curr = _base; |
ysr@777 | 69 | |
ysr@777 | 70 | for (size_t i = 0; i < group_num; ++i) { |
ysr@777 | 71 | guarantee( group_names[i] != NULL, "precondition" ); |
ysr@777 | 72 | _group_names[i] = group_names[i]; |
ysr@777 | 73 | } |
ysr@777 | 74 | } |
ysr@777 | 75 | |
ysr@777 | 76 | void |
ysr@777 | 77 | GCOverheadReporter::add(double start_sec, double end_sec, |
ysr@777 | 78 | double* conc_overhead, |
ysr@777 | 79 | double stw_overhead) { |
ysr@777 | 80 | assert( _curr <= _top, "invariant" ); |
ysr@777 | 81 | |
ysr@777 | 82 | if (_curr == _top) { |
ysr@777 | 83 | guarantee( false, "trace full" ); |
ysr@777 | 84 | return; |
ysr@777 | 85 | } |
ysr@777 | 86 | |
ysr@777 | 87 | _curr->_start_sec = start_sec; |
ysr@777 | 88 | _curr->_end_sec = end_sec; |
ysr@777 | 89 | for (size_t i = 0; i < _group_num; ++i) { |
ysr@777 | 90 | _curr->_conc_overhead[i] = |
ysr@777 | 91 | (conc_overhead != NULL) ? conc_overhead[i] : 0.0; |
ysr@777 | 92 | } |
ysr@777 | 93 | _curr->_stw_overhead = stw_overhead; |
ysr@777 | 94 | |
ysr@777 | 95 | ++_curr; |
ysr@777 | 96 | } |
ysr@777 | 97 | |
ysr@777 | 98 | void |
ysr@777 | 99 | GCOverheadReporter::collect_and_record_conc_overhead(double end_sec) { |
ysr@777 | 100 | double start_sec = _prev_end_sec; |
ysr@777 | 101 | guarantee( end_sec > start_sec, "invariant" ); |
ysr@777 | 102 | |
ysr@777 | 103 | double conc_overhead[MaxGCOverheadGroupNum]; |
ysr@777 | 104 | COTracker::totalConcOverhead(end_sec, _group_num, conc_overhead); |
ysr@777 | 105 | add_conc_overhead(start_sec, end_sec, conc_overhead); |
ysr@777 | 106 | _prev_end_sec = end_sec; |
ysr@777 | 107 | } |
ysr@777 | 108 | |
ysr@777 | 109 | void |
ysr@777 | 110 | GCOverheadReporter::record_stw_start(double start_sec) { |
ysr@777 | 111 | guarantee( start_sec > _prev_end_sec, "invariant" ); |
ysr@777 | 112 | collect_and_record_conc_overhead(start_sec); |
ysr@777 | 113 | } |
ysr@777 | 114 | |
ysr@777 | 115 | void |
ysr@777 | 116 | GCOverheadReporter::record_stw_end(double end_sec) { |
ysr@777 | 117 | double start_sec = _prev_end_sec; |
ysr@777 | 118 | COTracker::updateAllForSTW(start_sec, end_sec); |
ysr@777 | 119 | add_stw_overhead(start_sec, end_sec, 1.0); |
ysr@777 | 120 | |
ysr@777 | 121 | _prev_end_sec = end_sec; |
ysr@777 | 122 | } |
ysr@777 | 123 | |
ysr@777 | 124 | void |
ysr@777 | 125 | GCOverheadReporter::print() const { |
ysr@777 | 126 | tty->print_cr(""); |
ysr@777 | 127 | tty->print_cr("GC Overhead (%d entries)", _curr - _base); |
ysr@777 | 128 | tty->print_cr(""); |
ysr@777 | 129 | GCOverheadReporterEntry* curr = _base; |
ysr@777 | 130 | while (curr < _curr) { |
ysr@777 | 131 | double total = curr->_stw_overhead; |
ysr@777 | 132 | for (size_t i = 0; i < _group_num; ++i) |
ysr@777 | 133 | total += curr->_conc_overhead[i]; |
ysr@777 | 134 | |
ysr@777 | 135 | tty->print("OVERHEAD %12.8lf %12.8lf ", |
ysr@777 | 136 | curr->_start_sec, curr->_end_sec); |
ysr@777 | 137 | |
ysr@777 | 138 | for (size_t i = 0; i < _group_num; ++i) |
ysr@777 | 139 | tty->print("%s %12.8lf ", _group_names[i], curr->_conc_overhead[i]); |
ysr@777 | 140 | |
ysr@777 | 141 | tty->print_cr("STW %12.8lf TOT %12.8lf", curr->_stw_overhead, total); |
ysr@777 | 142 | ++curr; |
ysr@777 | 143 | } |
ysr@777 | 144 | tty->print_cr(""); |
ysr@777 | 145 | } |
ysr@777 | 146 | |
ysr@777 | 147 | // statics |
ysr@777 | 148 | |
ysr@777 | 149 | void |
ysr@777 | 150 | GCOverheadReporter::initGCOverheadReporter(size_t group_num, |
ysr@777 | 151 | const char* group_names[]) { |
ysr@777 | 152 | guarantee( _reporter == NULL, "should only be called once" ); |
ysr@777 | 153 | guarantee( 0 <= group_num && group_num <= MaxGCOverheadGroupNum, |
ysr@777 | 154 | "precondition" ); |
ysr@777 | 155 | guarantee( group_names != NULL, "pre-condition" ); |
ysr@777 | 156 | |
ysr@777 | 157 | if (GCOverheadReporting) { |
ysr@777 | 158 | _reporter = new GCOverheadReporter(group_num, group_names); |
ysr@777 | 159 | new COReportingThread(_reporter); |
ysr@777 | 160 | } |
ysr@777 | 161 | } |
ysr@777 | 162 | |
ysr@777 | 163 | void |
ysr@777 | 164 | GCOverheadReporter::recordSTWStart(double start_sec) { |
ysr@777 | 165 | if (_reporter != NULL) |
ysr@777 | 166 | _reporter->record_stw_start(start_sec); |
ysr@777 | 167 | } |
ysr@777 | 168 | |
ysr@777 | 169 | void |
ysr@777 | 170 | GCOverheadReporter::recordSTWEnd(double end_sec) { |
ysr@777 | 171 | if (_reporter != NULL) |
ysr@777 | 172 | _reporter->record_stw_end(end_sec); |
ysr@777 | 173 | } |
ysr@777 | 174 | |
ysr@777 | 175 | void |
ysr@777 | 176 | GCOverheadReporter::printGCOverhead() { |
ysr@777 | 177 | if (_reporter != NULL) |
ysr@777 | 178 | _reporter->print(); |
ysr@777 | 179 | } |