--- 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));