1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| while (true) { LockWord lock_word = h_obj->GetLockWord(false); switch (lock_word.GetState()) { case LockWord::kUnlocked: { LockWord thin_locked(LockWord::FromThinLockId(thread_id, 0, lock_word.GCState())); if (h_obj->CasLockWord(lock_word, thin_locked, CASMode::kWeak, std::memory_order_acquire)) { AtraceMonitorLock(self, h_obj.Get(), false); return h_obj.Get(); } continue; } case LockWord::kThinLocked: { uint32_t owner_thread_id = lock_word.ThinLockOwner(); if (owner_thread_id == thread_id) { uint32_t new_count = lock_word.ThinLockCount() + 1; if (LIKELY(new_count <= LockWord::kThinLockMaxCount)) { LockWord thin_locked(LockWord::FromThinLockId(thread_id, new_count, lock_word.GCState())); if (!kUseReadBarrier) { h_obj->SetLockWord(thin_locked, false); AtraceMonitorLock(self, h_obj.Get(), false); return h_obj.Get(); } else { if (h_obj->CasLockWord(lock_word, thin_locked, CASMode::kWeak, std::memory_order_relaxed)) { AtraceMonitorLock(self, h_obj.Get(), false); return h_obj.Get(); } } continue; } else { InflateThinLocked(self, h_obj, lock_word, 0); } } else { if (trylock) { return nullptr; } contention_count++; Runtime* runtime = Runtime::Current(); if (contention_count <= kExtraSpinIters + runtime->GetMaxSpinsBeforeThinLockInflation()) { if (contention_count > kExtraSpinIters) { sched_yield(); } } else { contention_count = 0; InflateThinLocked(self, h_obj, lock_word, 0); } } continue; } case LockWord::kFatLocked: { std::atomic_thread_fence(std::memory_order_acquire); Monitor* mon = lock_word.FatLockMonitor(); if (trylock) { return mon->TryLock(self) ? h_obj.Get() : nullptr; } else { mon->Lock(self); DCHECK(mon->monitor_lock_.IsExclusiveHeld(self)); return h_obj.Get(); } } case LockWord::kHashCode: Inflate(self, nullptr, h_obj.Get(), lock_word.GetHashCode()); continue; default: { LOG(FATAL) << "Invalid monitor state " << lock_word.GetState(); UNREACHABLE(); } }
|