/* * Insert a rank that may be lower than the current rank in an * appropriate position in the stack. This should only be used after a * successful trylock of a lock with rank r. */ void insertRank(Rank r) { assert(r != RankUnranked); if (currentRank() <= r) { pushRank(r); return; } // Find the first real rank < r int i; for (i = tl_curRankDepth; i >= 0; i--) { if (tl_rankStack[i] < r && tl_rankStack[i] != RankUnranked) { break; } } memmove(&tl_rankStack[i+1], &tl_rankStack[i], sizeof(Rank) * (tl_curRankDepth - i)); tl_rankStack[i] = r; }
// 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; }