当前位置: 首页>>代码示例>>C++>>正文


C++ PendingTriggers类代码示例

本文整理汇总了C++中PendingTriggers的典型用法代码示例。如果您正苦于以下问题:C++ PendingTriggers类的具体用法?C++ PendingTriggers怎么用?C++ PendingTriggers使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了PendingTriggers类的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: enqueueInternal

void enqueueInternal(std::unique_ptr<WorkItem> gt) {
  if (PendingTriggers::s_destroyed) {
    return;
  }
  GenCount time = getTime();
  {
    GenCountGuard g;
    gt->m_gen = correctTime(time);
    s_tq.emplace_back(std::move(gt));
  }
}
开发者ID:MatmaRex,项目名称:hhvm,代码行数:11,代码来源:treadmill.cpp

示例2: finishRequest

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];
    }
}
开发者ID:serphen,项目名称:hiphop-php,代码行数:38,代码来源:treadmill.cpp

示例3: TRACE_SET_MOD

namespace HPHP {  namespace Treadmill {

TRACE_SET_MOD(treadmill);

namespace {

const int64_t ONE_SEC_IN_MICROSEC = 1000000;

pthread_mutex_t s_genLock = PTHREAD_MUTEX_INITIALIZER;
const GenCount kIdleGenCount = 0; // not processing any requests.
std::vector<GenCount> s_inflightRequests;
GenCount s_latestCount = 0;
std::atomic<GenCount> s_oldestRequestInFlight(0);

/*
 * The next 2 functions should be used to manage the generation count/time
 * in the treadmill for both the requests and the work items.
 * The pattern is to call getTime() outside of the lock and correctTime()
 * while holding the lock.
 * That pattern guarantees a monotonically increasing counter.
 * The resolution being microseconds should give us all the room we need
 * to accommodate requests and work items at any conceivable rate and
 * correctTime() should give us correct behavior at any granularity of
 * gettimeofday().
 */

/*
 * Return the current time in microseconds.
 * Usually called outside of the lock.
 */
GenCount getTime() {
  struct timeval time;
  gettimeofday(&time, nullptr);
  return time.tv_sec * ONE_SEC_IN_MICROSEC + time.tv_usec;
}

/*
 * Return a monotonically increasing time given the last time recorded.
 * This must be called while holding the lock.
 */
GenCount correctTime(GenCount time) {
  s_latestCount = time <= s_latestCount ? s_latestCount + 1 : time;
  return s_latestCount;
}

struct GenCountGuard {
  GenCountGuard() {
    checkRank(RankTreadmill);
    pthread_mutex_lock(&s_genLock);
    pushRank(RankTreadmill);
  }
  ~GenCountGuard() {
    popRank(RankTreadmill);
    pthread_mutex_unlock(&s_genLock);
  }
};
}

typedef std::list<std::unique_ptr<WorkItem>> PendingTriggers;
static PendingTriggers s_tq;

// Inherently racy. We get a lower bound on the generation; presumably
// clients are aware of this, and are creating the trigger for an object
// that was reachable strictly in the past.
WorkItem::WorkItem() : m_gen(0) {
}

void WorkItem::enqueue(std::unique_ptr<Treadmill::WorkItem> gt) {
  GenCount time = getTime();
  {
    GenCountGuard g;
    gt->m_gen = correctTime(time);
    s_tq.emplace_back(std::move(gt));
  }
}

void startRequest(int threadId) {
  GenCount startTime = getTime();
  {
    GenCountGuard g;
    assert(threadId >= s_inflightRequests.size() ||
           s_inflightRequests[threadId] == kIdleGenCount);
    if (threadId >= s_inflightRequests.size()) {
      s_inflightRequests.resize(threadId + 1, kIdleGenCount);
    }
    s_inflightRequests[threadId] = correctTime(startTime);
    TRACE(1, "tid %d start @gen %lu\n", threadId, s_inflightRequests[threadId]);
    if (s_oldestRequestInFlight.load(std::memory_order_relaxed) == 0) {
      s_oldestRequestInFlight = s_inflightRequests[threadId];
    }
  }
}

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];
//.........这里部分代码省略.........
开发者ID:DirektSPEED,项目名称:hhvm,代码行数:101,代码来源:treadmill.cpp

示例4: TRACE_SET_MOD


//.........这里部分代码省略.........
//////////////////////////////////////////////////////////////////////

pthread_t getOldestRequestThreadId() {
  int64_t oldestStart = s_oldestRequestInFlight.load(std::memory_order_relaxed);
  for (auto& req : s_inflightRequests) {
    if (req.startTime == oldestStart) return req.pthreadId;
  }
  not_reached();
}

void checkOldest() {
  int64_t limit =
    RuntimeOption::MaxRequestAgeFactor * RuntimeOption::RequestTimeoutSeconds;
  if (!limit) return;

  int64_t ageOldest = getAgeOldestRequest();
  if (ageOldest > limit) {
    auto msg = folly::format("Oldest request has been running for {} "
                             "seconds. Aborting the server.", ageOldest).str();
    Logger::Error(msg);
    pthread_t oldestTid = getOldestRequestThreadId();
    pthread_kill(oldestTid, SIGABRT);
  }
}

void refreshStats() {
  static ServiceData::ExportedCounter* s_oldestRequestAgeStat =
    ServiceData::createCounter("treadmill.age");
  s_oldestRequestAgeStat->setValue(getAgeOldestRequest());
}

}

struct PendingTriggers : std::list<std::unique_ptr<WorkItem>> {
  ~PendingTriggers() {
    s_destroyed = true;
  }
  static bool s_destroyed;
};

static PendingTriggers s_tq;
bool PendingTriggers::s_destroyed = false;
void enqueueInternal(std::unique_ptr<WorkItem> gt) {
  if (PendingTriggers::s_destroyed) {
    return;
  }
  GenCount time = getTime();
  {
    GenCountGuard g;
    gt->m_gen = correctTime(time);
    s_tq.emplace_back(std::move(gt));
  }
}

void startRequest() {
  auto const threadIdx = Treadmill::threadIdx();

  GenCount startTime = getTime();
  {
    GenCountGuard g;
    refreshStats();
    checkOldest();
    if (threadIdx >= s_inflightRequests.size()) {
      s_inflightRequests.resize(threadIdx + 1, {kIdleGenCount, 0});
    } else {
      assert(s_inflightRequests[threadIdx].startTime == kIdleGenCount);
开发者ID:MatmaRex,项目名称:hhvm,代码行数:67,代码来源:treadmill.cpp

示例5: TRACE_SET_MOD

namespace Treadmill {

TRACE_SET_MOD(treadmill);

namespace {
static pthread_mutex_t s_genLock = PTHREAD_MUTEX_INITIALIZER;
static GenCount s_gen = 1;
static const GenCount kIdleGenCount = 0; // not processing any requests.
static GenCount* s_inflightRequests;
static int s_maxThreadID;

struct GenCountGuard {
    GenCountGuard() {
        checkRank(RankTreadmill);
        pthread_mutex_lock(&s_genLock);
        pushRank(RankTreadmill);
        if (!s_inflightRequests) {
            s_maxThreadID = 2;
            s_inflightRequests = (GenCount*)calloc(sizeof(GenCount), s_maxThreadID);
            static_assert(kIdleGenCount == 0, "kIdleGenCount should be zero");
        }
    }
    ~GenCountGuard() {
        popRank(RankTreadmill);
        pthread_mutex_unlock(&s_genLock);
    }
};
}

static GenCount* idToCount(int threadID) {
    if (threadID >= s_maxThreadID) {
        int newSize = threadID + 1;
        s_inflightRequests = (GenCount*)realloc(s_inflightRequests,
                                                sizeof(GenCount) * newSize);
        for (int i = s_maxThreadID; i < newSize; i++) {
            s_inflightRequests[i] = kIdleGenCount;
        }
        s_maxThreadID = newSize;
    }
    return s_inflightRequests + threadID;
}

typedef std::list<WorkItem*> PendingTriggers;
static PendingTriggers s_tq;

// Inherently racy. We get a lower bound on the generation; presumably
// clients are aware of this, and are creating the trigger for an object
// that was reachable strictly in the past.
WorkItem::WorkItem() : m_gen(s_gen) {
}

void WorkItem::enqueue(WorkItem* gt) {
    GenCountGuard g;
    gt->m_gen = s_gen++;
    s_tq.push_back(gt);
}

void startRequest(int threadId) {
    GenCountGuard g;
    assert(*idToCount(threadId) == kIdleGenCount);
    TRACE(1, "tid %d start @gen %d\n", threadId, int(s_gen));
    *idToCount(threadId) = s_gen;
}

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];
//.........这里部分代码省略.........
开发者ID:serphen,项目名称:hiphop-php,代码行数:101,代码来源:treadmill.cpp

示例6: enqueueInternal

void enqueueInternal(std::unique_ptr<WorkItem> gt) {
  GenCount time = getTime();
  {
    GenCountGuard g;
    gt->m_gen = correctTime(time);
    s_tq.emplace_back(std::move(gt));
  }
}
开发者ID:N3X15,项目名称:hhvm,代码行数:8,代码来源:treadmill.cpp

示例7: enqueue

void WorkItem::enqueue(std::unique_ptr<Treadmill::WorkItem> gt) {
  GenCount time = getTime();
  {
    GenCountGuard g;
    gt->m_gen = correctTime(time);
    s_tq.emplace_back(std::move(gt));
  }
}
开发者ID:DirektSPEED,项目名称:hhvm,代码行数:8,代码来源:treadmill.cpp

示例8: finishRequest

void finishRequest() {
  auto const threadIdx = Treadmill::threadIdx();
  assert(threadIdx != -1);
  FTRACE(1, "tid {} finish\n", threadIdx);
  std::vector<std::unique_ptr<WorkItem>> toFire;
  {
    GenCountGuard g;
    assert(s_inflightRequests[threadIdx].startTime != kIdleGenCount);
    GenCount finishedRequest = s_inflightRequests[threadIdx].startTime;
    s_inflightRequests[threadIdx].startTime = 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.startTime != kIdleGenCount && val.startTime < limit) {
          limit = val.startTime;
        }
      }
      // 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]->run();
  }
}
开发者ID:MatmaRex,项目名称:hhvm,代码行数:44,代码来源:treadmill.cpp

示例9: enqueue

void WorkItem::enqueue(WorkItem* gt) {
    GenCountGuard g;
    gt->m_gen = s_gen++;
    s_tq.push_back(gt);
}
开发者ID:serphen,项目名称:hiphop-php,代码行数:5,代码来源:treadmill.cpp


注:本文中的PendingTriggers类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。