Lease::~Lease() { if (amOwner()) { // Can happen, e.g., in exception scenarios. pthread_mutex_unlock(&m_lock); } pthread_mutex_destroy(&m_lock); }
void Lease::gremlinLock() { if (amOwner()) { TRACE(2, "Lease: gremlinLock dropping lease\n"); drop(); } pthread_mutex_lock(&m_lock); TRACE(2, "Lease: gremlin grabbed lock\n "); m_held = true; m_owner = gremlinize_threadid(pthread_self()); }
void Lease::drop(int64_t hintExpireDelay) { assertx(amOwner()); TRACE(4, "thr%" PRIx64 ": dropping lease, called by %p,%p\n", Process::GetThreadIdForTrace(), __builtin_return_address(0), __builtin_return_address(1)); if (debug) { popRank(RankWriteLease); } m_hintExpire = hintExpireDelay > 0 ? Timer::GetCurrentTimeMicros() + hintExpireDelay : 0; m_held.store(false, std::memory_order_release); pthread_mutex_unlock(&m_lock); }
void Lease::drop(int64 hintExpireDelay) { assert(amOwner()); TRACE(4, "thr%lx: dropping lease, called by %p,%p\n", pthread_self(), __builtin_return_address(0), __builtin_return_address(1)); if (debug) { popRank(RankWriteLease); Translator::Get()->protectCode(); } m_hintExpire = hintExpireDelay > 0 ? Timer::GetCurrentTimeMicros() + hintExpireDelay : 0; m_held = false; pthread_mutex_unlock(&m_lock); }
// acquire: also returns true if we are already the writer. bool Lease::acquire(bool blocking /* = false */ ) { if (amOwner()) { return true; } if (!threadCanAcquire && !blocking) { return false; } int64_t expire = m_hintExpire; int64_t expireDiff = expire - Timer::GetCurrentTimeMicros(); if (!blocking && (m_held.load(std::memory_order_acquire) || (expireDiff > 0 && m_owner != pthread_self()))) { return false; } checkRank(RankWriteLease); auto const locked = blocking ? pthread_mutex_lock(&m_lock) : pthread_mutex_trylock(&m_lock); if (locked == 0) { TRACE(4, "thr%" PRIx64 ": acquired lease, called by %p,%p\n", Process::GetThreadIdForTrace(), __builtin_return_address(0), __builtin_return_address(1)); if (debug) { pushRank(RankWriteLease); if (expire != 0 && m_owner != pthread_self()) { m_hintGrabbed++; TRACE(3, "thr%" PRIx64 ": acquired hinted lease" ", expired %" PRId64 "us ago\n", Process::GetThreadIdForTrace(), -expireDiff); } else if (expire != 0 && m_owner == pthread_self()) { m_hintKept++; } } m_owner = pthread_self(); m_hintExpire = 0; m_held.store(true, std::memory_order_release); return true; } always_assert(!blocking && "Failed to acquire write lease in blocking mode"); return false; }
// acquire: also returns true if we are already the writer. bool Lease::acquire(bool blocking /* = false */ ) { if (amOwner()) { return true; } int64_t expire = m_hintExpire; int64_t expireDiff = expire - Timer::GetCurrentTimeMicros(); if (!blocking && (m_held || (expireDiff > 0 && m_owner != pthread_self()))) { return false; } checkRank(RankWriteLease); if (0 == (blocking ? pthread_mutex_lock(&m_lock) : pthread_mutex_trylock(&m_lock))) { TRACE(4, "thr%" PRIx64 ": acquired lease, called by %p,%p\n", Process::GetThreadIdForTrace(), __builtin_return_address(0), __builtin_return_address(1)); if (debug) { pushRank(RankWriteLease); if (expire != 0 && m_owner != pthread_self()) { m_hintGrabbed++; TRACE(3, "thr%" PRIx64 ": acquired hinted lease" ", expired %" PRId64 "us ago\n", Process::GetThreadIdForTrace(), -expireDiff); } else if (expire != 0 && m_owner == pthread_self()) { m_hintKept++; } tx64->unprotectCode(); } m_owner = pthread_self(); m_hintExpire = 0; m_held = true; return true; } if (blocking) { TRACE(3, "thr%" PRIx64 ": failed to acquired lease in blocking mode\n", Process::GetThreadIdForTrace()); } return false; }