void insertAtRank (int rank, const Object& element)// insert at given rank { if (rank == size()) // no checkRank if last insertLast(element); else { checkRank(rank); insertBefore( atRank(rank), element ); } }
NodeSequence<Object>::Position NodeSequence<Object>:: atRank(int rank) const // position of rank { NodePtr v; checkRank(rank); if (rank <= size()/2) { // scan forward from head v = header->next; for (int i = 0; i < rank; i++) v = v->next; } else { // scan back from tail v = trailer->prev; for (int i = 1; i < size()-rank; i++) v = v->prev; } return Position(v); }
// 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; }
void replaceAtRank (int rank, const Object& element)// replace at rank { checkRank(rank); replaceElement( atRank(rank), element ); }
void removeAtRank (int rank) // remove from rank { checkRank(rank); Position p = atRank(rank); // position to remove remove(p); }
Object elemAtRank (int rank) const // element at this rank { checkRank(rank); return atRank(rank).element(); }
void pushRank(Rank r) { checkRank(r); assert(tl_curRankDepth < kMaxLockDepth); tl_rankStack[tl_curRankDepth++] = r; }