160 *
161 * Here, we have rendezvous with concurrent thread that adds up the budget as it acknowledges
162 * it had seen recent allocations. It will naturally pace the allocations if control thread is
163 * not catching up. To bootstrap this feedback cycle, we need to start with some initial budget
164 * for applications to allocate at.
165 */
166
167 void ShenandoahPacer::setup_for_idle() {
168 assert(ShenandoahPacing, "Only be here when pacing is enabled");
169
170 size_t initial = _heap->max_capacity() / 100 * ShenandoahPacingIdleSlack;
171 double tax = 1;
172
173 restart_with(initial, tax);
174
175 log_info(gc, ergo)("Pacer for Idle. Initial: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx",
176 byte_size_in_proper_unit(initial), proper_unit_for_byte_size(initial),
177 tax);
178 }
179
180 size_t ShenandoahPacer::update_and_get_progress_history() {
181 if (_progress == -1) {
182 // First initialization, report some prior
183 Atomic::store(&_progress, (intptr_t)PACING_PROGRESS_ZERO);
184 return (size_t) (_heap->max_capacity() * 0.1);
185 } else {
186 // Record history, and reply historical data
187 _progress_history->add(_progress);
188 Atomic::store(&_progress, (intptr_t)PACING_PROGRESS_ZERO);
189 return (size_t) (_progress_history->avg() * HeapWordSize);
190 }
191 }
192
193 void ShenandoahPacer::restart_with(size_t non_taxable_bytes, double tax_rate) {
194 size_t initial = (size_t)(non_taxable_bytes * tax_rate) >> LogHeapWordSize;
195 STATIC_ASSERT(sizeof(size_t) <= sizeof(intptr_t));
196 Atomic::xchg(&_budget, (intptr_t)initial);
197 Atomic::store(&_tax_rate, tax_rate);
198 Atomic::inc(&_epoch);
199 }
|
160 *
161 * Here, we have rendezvous with concurrent thread that adds up the budget as it acknowledges
162 * it had seen recent allocations. It will naturally pace the allocations if control thread is
163 * not catching up. To bootstrap this feedback cycle, we need to start with some initial budget
164 * for applications to allocate at.
165 */
166
167 void ShenandoahPacer::setup_for_idle() {
168 assert(ShenandoahPacing, "Only be here when pacing is enabled");
169
170 size_t initial = _heap->max_capacity() / 100 * ShenandoahPacingIdleSlack;
171 double tax = 1;
172
173 restart_with(initial, tax);
174
175 log_info(gc, ergo)("Pacer for Idle. Initial: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx",
176 byte_size_in_proper_unit(initial), proper_unit_for_byte_size(initial),
177 tax);
178 }
179
180 /*
181 * There is no useful notion of progress for these operations. To avoid stalling
182 * the allocators unnecessarily, allow them to run unimpeded.
183 */
184
185 void ShenandoahPacer::setup_for_preclean() {
186 assert(ShenandoahPacing, "Only be here when pacing is enabled");
187
188 size_t initial = _heap->max_capacity();
189 restart_with(initial, 1.0);
190
191 log_info(gc, ergo)("Pacer for Precleaning. Non-Taxable: " SIZE_FORMAT "%s",
192 byte_size_in_proper_unit(initial), proper_unit_for_byte_size(initial));
193 }
194
195 void ShenandoahPacer::setup_for_reset() {
196 assert(ShenandoahPacing, "Only be here when pacing is enabled");
197
198 size_t initial = _heap->max_capacity();
199 restart_with(initial, 1.0);
200
201 log_info(gc, ergo)("Pacer for Reset. Non-Taxable: " SIZE_FORMAT "%s",
202 byte_size_in_proper_unit(initial), proper_unit_for_byte_size(initial));
203 }
204
205 size_t ShenandoahPacer::update_and_get_progress_history() {
206 if (_progress == -1) {
207 // First initialization, report some prior
208 Atomic::store(&_progress, (intptr_t)PACING_PROGRESS_ZERO);
209 return (size_t) (_heap->max_capacity() * 0.1);
210 } else {
211 // Record history, and reply historical data
212 _progress_history->add(_progress);
213 Atomic::store(&_progress, (intptr_t)PACING_PROGRESS_ZERO);
214 return (size_t) (_progress_history->avg() * HeapWordSize);
215 }
216 }
217
218 void ShenandoahPacer::restart_with(size_t non_taxable_bytes, double tax_rate) {
219 size_t initial = (size_t)(non_taxable_bytes * tax_rate) >> LogHeapWordSize;
220 STATIC_ASSERT(sizeof(size_t) <= sizeof(intptr_t));
221 Atomic::xchg(&_budget, (intptr_t)initial);
222 Atomic::store(&_tax_rate, tax_rate);
223 Atomic::inc(&_epoch);
224 }
|