本文整理汇总了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));
}
}
示例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];
}
}
示例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];
//.........这里部分代码省略.........
示例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);
示例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];
//.........这里部分代码省略.........
示例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));
}
}
示例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));
}
}
示例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();
}
}
示例9: enqueue
void WorkItem::enqueue(WorkItem* gt) {
GenCountGuard g;
gt->m_gen = s_gen++;
s_tq.push_back(gt);
}