< prev index next >

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

Print this page
*** 26,13 ***
--- 26,51 ---
  
  #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 >