void AnalysisResult::processScopesParallel(const char *id, void *context /* = NULL */) { BlockScopeRawPtrQueue scopes; getScopesSet(scopes); DepthFirstVisitor<When, OptVisitor> dfv( OptVisitor<When>(shared_from_this(), scopes.size())); bool first = true; bool again; dfv.data().start(); do { BlockScopeRawPtrQueue enqueued; again = dfv.visitParallel(scopes, first, enqueued); preWaitCallback<When>(first, scopes, context); dfv.data().wait(); assert(!dfv.data().getQueuedJobs()); assert(!dfv.data().getActiveWorker()); again = postWaitCallback<When>(first, again, scopes, context); first = false; } while (again); dfv.data().stop(); for (BlockScopeRawPtrQueue::iterator it = scopes.begin(), end = scopes.end(); it != end; ++it) { assert((*it)->getMark() == BlockScope::MarkProcessed); assert((*it)->getNumDepsToWaitFor() == 0); assert((*it)->rescheduleFlags() == 0); } }
void AnalysisResult::processScopesParallel(const char *id, void* context /* = NULL */) { BlockScopeRawPtrQueue scopes; getScopesSet(scopes); DepthFirstVisitor dfv(OptVisitor(shared_from_this(), scopes.size())); bool first = true; bool again; dfv.data().start(); do { BlockScopeRawPtrQueue enqueued; again = dfv.visitParallel(scopes, first, enqueued); dfv.data().wait(); assert(!dfv.data().getQueuedJobs()); assert(!dfv.data().getActiveWorker()); first = false; } while (again); dfv.data().stop(); if (debug) { for (DEBUG_ONLY auto& scope : scopes) { assert(scope->getMark() == BlockScope::MarkProcessed); assert(scope->getNumDepsToWaitFor() == 0); assert(scope->rescheduleFlags() == 0); } } }
static inline int CountScopesWaiting(const BlockScopeRawPtrQueue &scopes) { int s = 0; for (BlockScopeRawPtrQueue::const_iterator it = scopes.begin(); it != scopes.end(); ++it) { int m = (*it)->getMark(); assert(m == BlockScope::MarkWaiting || m == BlockScope::MarkProcessed); if (m == BlockScope::MarkWaiting) s++; } return s; }
void FileScope::getScopesSet(BlockScopeRawPtrQueue &v) { for (const auto& clsVec : getClasses()) { for (const auto cls : clsVec.second) { if (cls->getStmt()) { v.push_back(cls); getFuncScopesSet(v, cls->getFunctions()); } } } getFuncScopesSet(v, getFunctions()); if (const auto redec = m_redeclaredFunctions) { for (const auto& funcVec : *redec) { auto i = funcVec.second.begin(), e = funcVec.second.end(); v.insert(v.end(), ++i, e); } } }
static void getFuncScopesSet(BlockScopeRawPtrQueue &v, const StringToFunctionScopePtrMap &funcMap) { for (const auto& iter : funcMap) { FunctionScopePtr f = iter.second; if (!f->isBuiltin()) { v.push_back(f); } } }
void AnalysisResult::processScopesParallel(const char *id, void *context /* = NULL */) { BlockScopeRawPtrQueue scopes; getScopesSet(scopes); #ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL std::cout << "processScopesParallel(" << id << "): " << scopes.size() << " scopes" << std::endl; #endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */ DepthFirstVisitor<When, OptVisitor> dfv( OptVisitor<When>(shared_from_this(), scopes.size())); bool first = true; bool again; dfv.data().start(); do { #ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL std::cout << "-----------------------------------" << std::endl; AnalysisResult::s_NumDoJobCalls = 0; AnalysisResult::s_NumForceRerunGlobal = 0; AnalysisResult::s_NumReactivateGlobal = 0; AnalysisResult::s_NumForceRerunUseKinds = 0; AnalysisResult::s_NumReactivateUseKinds = 0; AnalysisResult::s_DoJobUniqueScopes.clear(); #endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */ #ifdef HPHP_INSTRUMENT_TYPE_INF assert(RescheduleException::s_NumReschedules == 0); assert(RescheduleException::s_NumForceRerunSelfCaller == 0); assert(RescheduleException::s_NumRetTypesChanged == 0); assert(BaseTryLock::s_LockProfileMap.empty()); #endif /* HPHP_INSTRUMENT_TYPE_INF */ BlockScopeRawPtrQueue enqueued; again = dfv.visitParallel(scopes, first, enqueued); preWaitCallback<When>(first, scopes, context); #ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL { std::cout << "Enqueued " << enqueued.size() << " scopes in visitParallel()" << std::endl; if (enqueued.size() < 100) { for (BlockScopeRawPtrQueue::const_iterator it = enqueued.begin(); it != enqueued.end(); ++it) { DumpScopeWithDeps(*it); } } Timer timer(Timer::WallTime, "dfv.wait()"); dfv.data().wait(); } #else dfv.data().wait(); #endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */ assert(!dfv.data().getQueuedJobs()); assert(!dfv.data().getActiveWorker()); #ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL std::cout << "Number of doJob() calls: " << AnalysisResult::s_NumDoJobCalls << std::endl; std::cout << "Number of scopes which got doJob() called: " << AnalysisResult::s_DoJobUniqueScopes.size() << std::endl; std::vector<BIPair> v( AnalysisResult::s_DoJobUniqueScopes.begin(), AnalysisResult::s_DoJobUniqueScopes.end()); if (!v.empty()) { sort(v.begin(), v.end(), BIPairCmp()); std::vector<BIPair>::const_iterator end = v.size() > 20 ? v.begin() + 20 : v.end(); for (std::vector<BIPair>::const_iterator it = v.begin(); it != end; ++it) { auto prefix = folly::to<string>((*it).second, " times: "); DumpScope((*it).first, prefix.c_str()); } std::cout << "Number of global force reruns: " << AnalysisResult::s_NumForceRerunGlobal << std::endl; std::cout << "Number of global reactivates: " << AnalysisResult::s_NumReactivateGlobal << std::endl; std::cout << "Number of use kind force reruns: " << AnalysisResult::s_NumForceRerunUseKinds << std::endl; std::cout << "Number of use kind reactivates: " << AnalysisResult::s_NumReactivateUseKinds << std::endl; } int numWaiting = CountScopesWaiting(scopes); std::cout << "Number of waiting scopes: " << numWaiting << std::endl; #endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */ again = postWaitCallback<When>(first, again, scopes, context); first = false; } while (again); dfv.data().stop(); for (BlockScopeRawPtrQueue::iterator it = scopes.begin(), end = scopes.end(); it != end; ++it) { assert((*it)->getMark() == BlockScope::MarkProcessed); assert((*it)->getNumDepsToWaitFor() == 0); assert(!(*it)->needsReschedule()); assert((*it)->rescheduleFlags() == 0); } }