Exemplo n.º 1
0
/*
 * 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;
}
Exemplo n.º 2
0
// 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;
}
Exemplo n.º 3
0
// 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;
}