Skip to content

Commit 92f2ab2

Browse files
author
William Kemper
committed
8264851: Shenandoah: Rework control loop mechanics to use timed waits
Reviewed-by: kdnilsen, shade
1 parent ac73e68 commit 92f2ab2

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
ShenandoahControlThread::ShenandoahControlThread() :
4444
ShenandoahController(),
4545
_requested_gc_cause(GCCause::_no_gc),
46-
_degen_point(ShenandoahGC::_degenerated_outside_cycle) {
46+
_degen_point(ShenandoahGC::_degenerated_outside_cycle),
47+
_control_lock(Mutex::nosafepoint - 2, "ShenandoahGCRequest_lock", true) {
4748
set_name("Shenandoah Control Thread");
4849
create_and_start();
4950
}
@@ -228,7 +229,9 @@ void ShenandoahControlThread::run_service() {
228229
sleep = MIN2<int>(ShenandoahControlIntervalMax, MAX2(1, sleep * 2));
229230
last_sleep_adjust_time = current;
230231
}
231-
os::naked_short_sleep(sleep);
232+
233+
MonitorLocker ml(&_control_lock, Mutex::_no_safepoint_check_flag);
234+
ml.wait(sleep);
232235
}
233236
}
234237

@@ -343,6 +346,16 @@ void ShenandoahControlThread::request_gc(GCCause::Cause cause) {
343346
}
344347
}
345348

349+
void ShenandoahControlThread::notify_control_thread(GCCause::Cause cause) {
350+
// Although setting gc request is under _controller_lock, the read side (run_service())
351+
// does not take the lock. We need to enforce following order, so that read side sees
352+
// latest requested gc cause when the flag is set.
353+
MonitorLocker controller(&_control_lock, Mutex::_no_safepoint_check_flag);
354+
_requested_gc_cause = cause;
355+
_gc_requested.set();
356+
controller.notify();
357+
}
358+
346359
void ShenandoahControlThread::handle_requested_gc(GCCause::Cause cause) {
347360
if (should_terminate()) {
348361
log_info(gc)("Control thread is terminating, no more GCs");
@@ -354,8 +367,7 @@ void ShenandoahControlThread::handle_requested_gc(GCCause::Cause cause) {
354367
// The whitebox caller thread will arrange for itself to wait until the GC notifies
355368
// it that has reached the requested breakpoint (phase in the GC).
356369
if (cause == GCCause::_wb_breakpoint) {
357-
_requested_gc_cause = cause;
358-
_gc_requested.set();
370+
notify_control_thread(cause);
359371
return;
360372
}
361373

@@ -372,12 +384,7 @@ void ShenandoahControlThread::handle_requested_gc(GCCause::Cause cause) {
372384
size_t current_gc_id = get_gc_id();
373385
size_t required_gc_id = current_gc_id + 1;
374386
while (current_gc_id < required_gc_id && !should_terminate()) {
375-
// Although setting gc request is under _gc_waiters_lock, but read side (run_service())
376-
// does not take the lock. We need to enforce following order, so that read side sees
377-
// latest requested gc cause when the flag is set.
378-
_requested_gc_cause = cause;
379-
_gc_requested.set();
380-
387+
notify_control_thread(cause);
381388
ml.wait();
382389
current_gc_id = get_gc_id();
383390
}

src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class ShenandoahControlThread: public ShenandoahController {
4545
GCCause::Cause _requested_gc_cause;
4646
ShenandoahGC::ShenandoahDegenPoint _degen_point;
4747

48+
// This lock is used to coordinate waking up the control thread
49+
Monitor _control_lock;
50+
4851
public:
4952
ShenandoahControlThread();
5053

@@ -54,6 +57,8 @@ class ShenandoahControlThread: public ShenandoahController {
5457
void request_gc(GCCause::Cause cause) override;
5558

5659
private:
60+
// Sets the requested cause and flag and notifies the control thread
61+
void notify_control_thread(GCCause::Cause cause);
5762

5863
bool check_cancellation_or_degen(ShenandoahGC::ShenandoahDegenPoint point);
5964
void service_concurrent_normal_cycle(GCCause::Cause cause);

0 commit comments

Comments
 (0)