Skip to content

Commit c1ad393

Browse files
author
William Kemper
committed
8374048: Genshen: Backout fix for missed cancellation notice
Reviewed-by: kdnilsen, ysr
1 parent 23fc21a commit c1ad393

File tree

2 files changed

+19
-15
lines changed

2 files changed

+19
-15
lines changed

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

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ void ShenandoahGenerationalControlThread::stop_service() {
9696
log_debug(gc, thread)("Stopping control thread");
9797
MonitorLocker ml(&_control_lock, Mutex::_no_safepoint_check_flag);
9898
_heap->cancel_gc(GCCause::_shenandoah_stop_vm);
99-
notify_control_thread(ml, GCCause::_shenandoah_stop_vm);
99+
_requested_gc_cause = GCCause::_shenandoah_stop_vm;
100+
notify_cancellation(ml, GCCause::_shenandoah_stop_vm);
100101
// We can't wait here because it may interfere with the active cycle's ability
101102
// to reach a safepoint (this runs on a java thread).
102103
}
@@ -139,8 +140,7 @@ void ShenandoahGenerationalControlThread::check_for_request(ShenandoahGCRequest&
139140
}
140141

141142
ShenandoahGenerationalControlThread::GCMode ShenandoahGenerationalControlThread::prepare_for_allocation_failure_gc(ShenandoahGCRequest &request) {
142-
// Important: not all paths update the request.generation. This is intentional.
143-
// A degenerated cycle must use the same generation carried over from the previous request.
143+
144144
if (_degen_point == ShenandoahGC::_degenerated_unset) {
145145
_degen_point = ShenandoahGC::_degenerated_outside_cycle;
146146
request.generation = _heap->young_generation();
@@ -633,7 +633,9 @@ void ShenandoahGenerationalControlThread::service_stw_degenerated_cycle(const Sh
633633

634634
void ShenandoahGenerationalControlThread::request_gc(GCCause::Cause cause) {
635635
if (ShenandoahCollectorPolicy::is_allocation_failure(cause)) {
636-
notify_control_thread(cause);
636+
// GC should already be cancelled. Here we are just notifying the control thread to
637+
// wake up and handle the cancellation request, so we don't need to set _requested_gc_cause.
638+
notify_cancellation(cause);
637639
} else if (ShenandoahCollectorPolicy::should_handle_requested_gc(cause)) {
638640
handle_requested_gc(cause);
639641
}
@@ -659,7 +661,7 @@ bool ShenandoahGenerationalControlThread::request_concurrent_gc(ShenandoahGenera
659661
log_info(gc)("Preempting old generation mark to allow %s GC", generation->name());
660662
while (gc_mode() == servicing_old) {
661663
ShenandoahHeap::heap()->cancel_gc(GCCause::_shenandoah_concurrent_gc);
662-
notify_control_thread(ml, GCCause::_shenandoah_concurrent_gc);
664+
notify_cancellation(ml, GCCause::_shenandoah_concurrent_gc);
663665
ml.wait();
664666
}
665667
return true;
@@ -699,15 +701,14 @@ void ShenandoahGenerationalControlThread::notify_control_thread(MonitorLocker& m
699701
ml.notify();
700702
}
701703

702-
void ShenandoahGenerationalControlThread::notify_control_thread(GCCause::Cause cause) {
704+
void ShenandoahGenerationalControlThread::notify_cancellation(GCCause::Cause cause) {
703705
MonitorLocker ml(&_control_lock, Mutex::_no_safepoint_check_flag);
704-
notify_control_thread(ml, cause);
706+
notify_cancellation(ml, cause);
705707
}
706708

707-
void ShenandoahGenerationalControlThread::notify_control_thread(MonitorLocker& ml, GCCause::Cause cause) {
708-
assert(_control_lock.is_locked(), "Request lock must be held here");
709-
log_debug(gc, thread)("Notify control (%s): %s", gc_mode_name(gc_mode()), GCCause::to_string(cause));
710-
_requested_gc_cause = cause;
709+
void ShenandoahGenerationalControlThread::notify_cancellation(MonitorLocker& ml, GCCause::Cause cause) {
710+
assert(_heap->cancelled_gc(), "GC should already be cancelled");
711+
log_debug(gc,thread)("Notify control (%s): %s", gc_mode_name(gc_mode()), GCCause::to_string(cause));
711712
ml.notify();
712713
}
713714

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,16 @@ class ShenandoahGenerationalControlThread: public ShenandoahController {
135135
// Return printable name for the given gc mode.
136136
static const char* gc_mode_name(GCMode mode);
137137

138-
// These notify the control thread after updating _requested_gc_cause and (optionally) _requested_generation.
139-
// Updating the requested generation is not necessary for allocation failures nor when stopping the thread.
140-
void notify_control_thread(GCCause::Cause cause);
141-
void notify_control_thread(MonitorLocker& ml, GCCause::Cause cause);
138+
// Takes the request lock and updates the requested cause and generation, then notifies the control thread.
139+
// The overloaded variant should be used when the _control_lock is already held.
142140
void notify_control_thread(GCCause::Cause cause, ShenandoahGeneration* generation);
143141
void notify_control_thread(MonitorLocker& ml, GCCause::Cause cause, ShenandoahGeneration* generation);
144142

143+
// Notifies the control thread, but does not update the requested cause or generation.
144+
// The overloaded variant should be used when the _control_lock is already held.
145+
void notify_cancellation(GCCause::Cause cause);
146+
void notify_cancellation(MonitorLocker& ml, GCCause::Cause cause);
147+
145148
// Configure the heap to age objects and regions if the aging period has elapsed.
146149
void maybe_set_aging_cycle();
147150

0 commit comments

Comments
 (0)