Beispiel #1
0
void finishRequest(int threadId) {
  TRACE(1, "tid %d finish\n", threadId);
  std::vector<std::unique_ptr<WorkItem>> toFire;
  {
    GenCountGuard g;
    assert(s_inflightRequests[threadId] != kIdleGenCount);
    GenCount finishedRequest = s_inflightRequests[threadId];
    s_inflightRequests[threadId] = kIdleGenCount;

    // After finishing a request, check to see if we've allowed any triggers
    // to fire and update the time of the oldest request in flight.
    // However if the request just finished is not the current oldest we
    // don't need to check anything as there cannot be any WorkItem to run.
    if (s_oldestRequestInFlight.load(std::memory_order_relaxed) ==
        finishedRequest) {
      GenCount limit = s_latestCount + 1;
      for (auto val : s_inflightRequests) {
        if (val != kIdleGenCount && val < limit) {
          limit = val;
        }
      }
      // update "oldest in flight" or kill it if there are no running requests
      s_oldestRequestInFlight = limit == s_latestCount + 1 ? 0 : limit;

      // collect WorkItem to run
      auto it = s_tq.begin();
      auto end = s_tq.end();
      while (it != end) {
        TRACE(2, "considering delendum %d\n", int((*it)->m_gen));
        if ((*it)->m_gen >= limit) {
          TRACE(2, "not unreachable! %d\n", int((*it)->m_gen));
          break;
        }
        toFire.emplace_back(std::move(*it));
        it = s_tq.erase(it);
      }
    }
  }
  for (unsigned i = 0; i < toFire.size(); ++i) {
    (*toFire[i])();
  }
}
Beispiel #2
0
void finishRequest(int threadId) {
    TRACE(1, "tid %d finish\n", threadId);
    std::vector<WorkItem*> toFire;
    {
        GenCountGuard g;
        assert(*idToCount(threadId) != kIdleGenCount);
        *idToCount(threadId) = kIdleGenCount;

        // After finishing a request, check to see if we've allowed any triggers
        // to fire.
        PendingTriggers::iterator it = s_tq.begin();
        PendingTriggers::iterator end = s_tq.end();
        if (it != end) {
            GenCount gen = (*it)->m_gen;
            GenCount limit = s_gen + 1;
            for (int i = 0; i < s_maxThreadID; ++i) {
                if (s_inflightRequests[i] != kIdleGenCount &&
                        s_inflightRequests[i] < limit) {
                    limit = s_inflightRequests[i];
                    if (limit <= gen) break;
                }
            }
            do {
                TRACE(2, "considering delendum %d\n", int((*it)->m_gen));
                if ((*it)->m_gen >= limit) {
                    TRACE(2, "not unreachable! %d\n", int((*it)->m_gen));
                    break;
                }
                toFire.push_back(*it);
                it = s_tq.erase(it);
            } while (it != end);
        }
    }
    for (unsigned i = 0; i < toFire.size(); ++i) {
        (*toFire[i])();
        delete toFire[i];
    }
}