--- old/src/hotspot/share/gc/shenandoah/shenandoahSharedVariables.hpp 2020-06-01 12:25:24.849026038 +0200 +++ new/src/hotspot/share/gc/shenandoah/shenandoahSharedVariables.hpp 2020-06-01 12:25:24.533026448 +0200 @@ -245,4 +245,38 @@ }; +typedef struct ShenandoahSharedSemaphore { + shenandoah_padding(0); + volatile ShenandoahSharedValue value; + shenandoah_padding(1); + + static uint max_tokens() { + return sizeof(ShenandoahSharedValue) * CHAR_MAX; + } + + ShenandoahSharedSemaphore(uint tokens) { + assert(tokens <= max_tokens(), "sanity"); + Atomic::release_store_fence(&value, (ShenandoahSharedValue)tokens); + } + + bool try_acquire() { + while (true) { + ShenandoahSharedValue ov = Atomic::load_acquire(&value); + if (ov == 0) { + return false; + } + ShenandoahSharedValue nv = ov - 1; + if (Atomic::cmpxchg(&value, ov, nv) == ov) { + // successfully set + return true; + } + } + } + + void claim_all() { + Atomic::release_store_fence(&value, (ShenandoahSharedValue)0); + } + +} ShenandoahSharedSemaphore; + #endif // SHARE_GC_SHENANDOAH_SHENANDOAHSHAREDVARIABLES_HPP