< prev index next > src/hotspot/share/gc/shenandoah/shenandoahLock.cpp
Print this page
#include "runtime/os.hpp"
#include "gc/shenandoah/shenandoahLock.hpp"
#include "runtime/atomic.hpp"
+ #include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaThread.hpp"
#include "runtime/os.inline.hpp"
+ // These are inline variants of Thread::SpinAcquire with optional blocking in VM.
+
+ class ShenandoahNoBlockOp : public StackObj {
+ public:
+ ShenandoahNoBlockOp(JavaThread* java_thread) {
+ assert(java_thread == nullptr, "Should not pass anything");
+ }
+ };
+
+ void ShenandoahLock::contended_lock(bool allow_block_for_safepoint) {
+ Thread* thread = Thread::current();
+ if (allow_block_for_safepoint && thread->is_Java_thread()) {
+ contended_lock_internal<ThreadBlockInVM>(JavaThread::cast(thread));
+ } else {
+ contended_lock_internal<ShenandoahNoBlockOp>(nullptr);
+ }
+ }
+
+ template<typename BlockOp>
+ void ShenandoahLock::contended_lock_internal(JavaThread* java_thread) {
+ int ctr = 0;
+ int yields = 0;
+ while (Atomic::cmpxchg(&_state, unlocked, locked) != unlocked) {
+ if ((++ctr & 0xFFF) == 0) {
+ BlockOp block(java_thread);
+ if (yields > 5) {
+ os::naked_short_sleep(1);
+ } else {
+ os::naked_yield();
+ yields++;
+ }
+ } else {
+ SpinPause();
+ }
+ }
+ }
+
ShenandoahSimpleLock::ShenandoahSimpleLock() {
assert(os::mutex_init_done(), "Too early!");
}
void ShenandoahSimpleLock::lock() {
< prev index next >