diff -r dfacdb971494 -r 881c5fbeb849 src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Thu Jan 31 01:17:41 2019 +0100 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Thu Jan 31 10:31:39 2019 +0100 @@ -65,6 +65,8 @@ #include "gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp" #include "memory/metaspace.hpp" +#include "runtime/interfaceSupport.inline.hpp" +#include "runtime/safepointMechanism.hpp" #include "runtime/vmThread.hpp" #include "services/mallocTracker.hpp" @@ -1863,6 +1865,22 @@ return _free_set->used(); } +bool ShenandoahHeap::try_cancel_gc() { + while (true) { + jbyte prev = _cancelled_gc.cmpxchg(CANCELLED, CANCELLABLE); + if (prev == CANCELLABLE) return true; + else if (prev == CANCELLED) return false; + assert(ShenandoahSuspendibleWorkers, "should not get here when not using suspendible workers"); + assert(prev == NOT_CANCELLED, "must be NOT_CANCELLED"); + { + // We need to provide a safepoint here, otherwise we might + // spin forever if a SP is pending. + ThreadBlockInVM sp(JavaThread::current()); + SpinPause(); + } + } +} + void ShenandoahHeap::cancel_gc(GCCause::Cause cause) { if (try_cancel_gc()) { FormatBuffer<> msg("Cancelling GC: %s", GCCause::to_string(cause));