mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
8247593: Shenandoah: should not block pacing reporters
Reviewed-by: rkennke
This commit is contained in:
parent
6d2959b393
commit
aeeaffa888
5 changed files with 41 additions and 15 deletions
|
@ -53,6 +53,9 @@ ShenandoahControlThread::ShenandoahControlThread() :
|
||||||
create_and_start(ShenandoahCriticalControlThreadPriority ? CriticalPriority : NearMaxPriority);
|
create_and_start(ShenandoahCriticalControlThreadPriority ? CriticalPriority : NearMaxPriority);
|
||||||
_periodic_task.enroll();
|
_periodic_task.enroll();
|
||||||
_periodic_satb_flush_task.enroll();
|
_periodic_satb_flush_task.enroll();
|
||||||
|
if (ShenandoahPacing) {
|
||||||
|
_periodic_pacer_notify_task.enroll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ShenandoahControlThread::~ShenandoahControlThread() {
|
ShenandoahControlThread::~ShenandoahControlThread() {
|
||||||
|
@ -68,6 +71,11 @@ void ShenandoahPeriodicSATBFlushTask::task() {
|
||||||
ShenandoahHeap::heap()->force_satb_flush_all_threads();
|
ShenandoahHeap::heap()->force_satb_flush_all_threads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShenandoahPeriodicPacerNotify::task() {
|
||||||
|
assert(ShenandoahPacing, "Should not be here otherwise");
|
||||||
|
ShenandoahHeap::heap()->pacer()->notify_waiters();
|
||||||
|
}
|
||||||
|
|
||||||
void ShenandoahControlThread::run_service() {
|
void ShenandoahControlThread::run_service() {
|
||||||
ShenandoahHeap* heap = ShenandoahHeap::heap();
|
ShenandoahHeap* heap = ShenandoahHeap::heap();
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,13 @@ public:
|
||||||
virtual void task();
|
virtual void task();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Periodic task to notify blocked paced waiters.
|
||||||
|
class ShenandoahPeriodicPacerNotify : public PeriodicTask {
|
||||||
|
public:
|
||||||
|
ShenandoahPeriodicPacerNotify() : PeriodicTask(PeriodicTask::min_interval) {}
|
||||||
|
virtual void task();
|
||||||
|
};
|
||||||
|
|
||||||
class ShenandoahControlThread: public ConcurrentGCThread {
|
class ShenandoahControlThread: public ConcurrentGCThread {
|
||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
|
|
||||||
|
@ -70,6 +77,7 @@ private:
|
||||||
Monitor _gc_waiters_lock;
|
Monitor _gc_waiters_lock;
|
||||||
ShenandoahPeriodicTask _periodic_task;
|
ShenandoahPeriodicTask _periodic_task;
|
||||||
ShenandoahPeriodicSATBFlushTask _periodic_satb_flush_task;
|
ShenandoahPeriodicSATBFlushTask _periodic_satb_flush_task;
|
||||||
|
ShenandoahPeriodicPacerNotify _periodic_pacer_notify_task;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void run_service();
|
void run_service();
|
||||||
|
|
|
@ -193,7 +193,7 @@ void ShenandoahPacer::restart_with(size_t non_taxable_bytes, double tax_rate) {
|
||||||
Atomic::inc(&_epoch);
|
Atomic::inc(&_epoch);
|
||||||
|
|
||||||
// Shake up stalled waiters after budget update.
|
// Shake up stalled waiters after budget update.
|
||||||
notify_waiters();
|
_need_notify_waiters.try_set();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShenandoahPacer::claim_for_alloc(size_t words, bool force) {
|
bool ShenandoahPacer::claim_for_alloc(size_t words, bool force) {
|
||||||
|
@ -222,8 +222,8 @@ void ShenandoahPacer::unpace_for_alloc(intptr_t epoch, size_t words) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t tax = MAX2<intptr_t>(1, words * Atomic::load(&_tax_rate));
|
size_t tax = MAX2<size_t>(1, words * Atomic::load(&_tax_rate));
|
||||||
Atomic::add(&_budget, tax);
|
add_budget(tax);
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t ShenandoahPacer::epoch() {
|
intptr_t ShenandoahPacer::epoch() {
|
||||||
|
@ -288,8 +288,10 @@ void ShenandoahPacer::wait(size_t time_ms) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShenandoahPacer::notify_waiters() {
|
void ShenandoahPacer::notify_waiters() {
|
||||||
|
if (_need_notify_waiters.try_unset()) {
|
||||||
MonitorLocker locker(_wait_monitor);
|
MonitorLocker locker(_wait_monitor);
|
||||||
_wait_monitor->notify_all();
|
_wait_monitor->notify_all();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShenandoahPacer::print_on(outputStream* out) const {
|
void ShenandoahPacer::print_on(outputStream* out) const {
|
||||||
|
|
|
@ -46,6 +46,7 @@ private:
|
||||||
BinaryMagnitudeSeq _delays;
|
BinaryMagnitudeSeq _delays;
|
||||||
TruncatedSeq* _progress_history;
|
TruncatedSeq* _progress_history;
|
||||||
Monitor* _wait_monitor;
|
Monitor* _wait_monitor;
|
||||||
|
ShenandoahSharedFlag _need_notify_waiters;
|
||||||
|
|
||||||
// Set once per phase
|
// Set once per phase
|
||||||
volatile intptr_t _epoch;
|
volatile intptr_t _epoch;
|
||||||
|
@ -89,6 +90,8 @@ public:
|
||||||
void pace_for_alloc(size_t words);
|
void pace_for_alloc(size_t words);
|
||||||
void unpace_for_alloc(intptr_t epoch, size_t words);
|
void unpace_for_alloc(intptr_t epoch, size_t words);
|
||||||
|
|
||||||
|
void notify_waiters();
|
||||||
|
|
||||||
intptr_t epoch();
|
intptr_t epoch();
|
||||||
|
|
||||||
void print_on(outputStream* out) const;
|
void print_on(outputStream* out) const;
|
||||||
|
@ -97,12 +100,12 @@ private:
|
||||||
inline void report_internal(size_t words);
|
inline void report_internal(size_t words);
|
||||||
inline void report_progress_internal(size_t words);
|
inline void report_progress_internal(size_t words);
|
||||||
|
|
||||||
|
inline void add_budget(size_t words);
|
||||||
void restart_with(size_t non_taxable_bytes, double tax_rate);
|
void restart_with(size_t non_taxable_bytes, double tax_rate);
|
||||||
|
|
||||||
size_t update_and_get_progress_history();
|
size_t update_and_get_progress_history();
|
||||||
|
|
||||||
void wait(size_t time_ms);
|
void wait(size_t time_ms);
|
||||||
void notify_waiters();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHPACER_HPP
|
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHPACER_HPP
|
||||||
|
|
|
@ -47,15 +47,7 @@ inline void ShenandoahPacer::report_alloc(size_t words) {
|
||||||
|
|
||||||
inline void ShenandoahPacer::report_internal(size_t words) {
|
inline void ShenandoahPacer::report_internal(size_t words) {
|
||||||
assert(ShenandoahPacing, "Only be here when pacing is enabled");
|
assert(ShenandoahPacing, "Only be here when pacing is enabled");
|
||||||
STATIC_ASSERT(sizeof(size_t) <= sizeof(intptr_t));
|
add_budget(words);
|
||||||
intptr_t inc = (intptr_t) words;
|
|
||||||
intptr_t new_budget = Atomic::add(&_budget, inc);
|
|
||||||
|
|
||||||
// Was the budget replenished beyond zero? Then all pacing claims
|
|
||||||
// are satisfied, notify the waiters.
|
|
||||||
if (new_budget >= 0 && (new_budget - inc) < 0) {
|
|
||||||
notify_waiters();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void ShenandoahPacer::report_progress_internal(size_t words) {
|
inline void ShenandoahPacer::report_progress_internal(size_t words) {
|
||||||
|
@ -64,4 +56,17 @@ inline void ShenandoahPacer::report_progress_internal(size_t words) {
|
||||||
Atomic::add(&_progress, (intptr_t)words);
|
Atomic::add(&_progress, (intptr_t)words);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void ShenandoahPacer::add_budget(size_t words) {
|
||||||
|
STATIC_ASSERT(sizeof(size_t) <= sizeof(intptr_t));
|
||||||
|
intptr_t inc = (intptr_t) words;
|
||||||
|
intptr_t new_budget = Atomic::add(&_budget, inc);
|
||||||
|
|
||||||
|
// Was the budget replenished beyond zero? Then all pacing claims
|
||||||
|
// are satisfied, notify the waiters. Avoid taking any locks here,
|
||||||
|
// as it can be called from hot paths and/or while holding other locks.
|
||||||
|
if (new_budget >= 0 && (new_budget - inc) < 0) {
|
||||||
|
_need_notify_waiters.try_set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHPACER_INLINE_HPP
|
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHPACER_INLINE_HPP
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue