/** Copy another object to this one. * @param source is object to be copied to this one */ void PathSet::copyFrom(const PathSet& source) { if (&source == this) return; if (source.n() > n()) resize(source.n()); else clear(); for (index x = 1; x <= n(); x++) { pnode[x] = source.pnode[x]; pvals[x] = source.pvals[x]; } }
/* Create paths so one path funds another path. Two accounts: sender and receiver. Two gateways: gw1 and gw2. Sender and receiver both have trust lines to the gateways. Sender has 2 gw1/USD and 4 gw2/USD. Sender has offer to exchange 2 gw1 for gw2 and gw2 for gw1 1-for-1. Paths are: 1) GW1 -> [OB GW1/USD->GW2/USD] -> GW2 2) GW2 -> [OB GW2/USD->GW1/USD] -> GW1 sender pays receiver 4 USD. Path 1: 1) Sender exchanges 2 GW1/USD for 2 GW2/USD 2) Old code: the 2 GW1/USD is available to sender New code: the 2 GW1/USD is not available until the end of the transaction. 3) Receiver gets 2 GW2/USD Path 2: 1) Old code: Sender exchanges 2 GW2/USD for 2 GW1/USD 2) Old code: Receiver get 2 GW1 2) New code: Path is dry because sender does not have any GW1 to spend until the end of the transaction. */ void testSelfFunding (FeatureBitset features) { testcase ("selfFunding"); using namespace jtx; Env env (*this, features); Account const gw1 ("gw1"); Account const gw2 ("gw2"); Account const snd ("snd"); Account const rcv ("rcv"); env.fund (XRP (10000), snd, rcv, gw1, gw2); auto const USD_gw1 = gw1["USD"]; auto const USD_gw2 = gw2["USD"]; env.trust (USD_gw1 (10), snd); env.trust (USD_gw2 (10), snd); env.trust (USD_gw1 (100), rcv); env.trust (USD_gw2 (100), rcv); env (pay (gw1, snd, USD_gw1 (2))); env (pay (gw2, snd, USD_gw2 (4))); env (offer (snd, USD_gw1 (2), USD_gw2 (2)), txflags (tfPassive)); env (offer (snd, USD_gw2 (2), USD_gw1 (2)), txflags (tfPassive)); PathSet paths ( Path (gw1, USD_gw2, gw2), Path (gw2, USD_gw1, gw1)); env (pay (snd, rcv, any (USD_gw1 (4))), json (paths.json ()), txflags (tfNoRippleDirect | tfPartialPayment)); env.require (balance ("rcv", USD_gw1 (0))); env.require (balance ("rcv", USD_gw2 (2))); }
void TbTraceTool::flatTrace() { PathBuilder pb(&m_parser); m_parser.parse(TraceFiles); ModuleCache mc(&pb); TestCase tc(&pb); PathSet paths; pb.getPaths(paths); cl::list<unsigned>::const_iterator listit; if (PathList.empty()) { PathSet::iterator pit; for (pit = paths.begin(); pit != paths.end(); ++pit) { PathList.push_back(*pit); } } //XXX: this is efficient only for short paths or for a small number of //path, because complexity is O(n2): we reprocess the prefixes. for(listit = PathList.begin(); listit != PathList.end(); ++listit) { std::cout << "Processing path " << std::dec << *listit << std::endl; PathSet::iterator pit = paths.find(*listit); if (pit == paths.end()) { std::cerr << "Could not find path with id " << std::dec << *listit << " in the execution trace." << std::endl; continue; } std::stringstream ss; ss << LogDir << "/" << *listit << ".txt"; std::ofstream traceFile(ss.str().c_str()); TbTrace trace(&m_binaries, &mc, &pb, traceFile); if (!pb.processPath(*listit)) { std::cerr << "Could not process path " << std::dec << *listit << std::endl; continue; } traceFile << "----------------------" << std::endl; if (trace.hasDebugInfo() == false) { traceFile << "WARNING: No debug information for any module in the path " << std::dec << *listit << std::endl; traceFile << "WARNING: Make sure you have set the module path properly and the binaries contain debug information." << std::endl << std::endl; } if (trace.hasModuleInfo() == false) { traceFile << "WARNING: No module information for any module in the path " << std::dec << *listit << std::endl; traceFile << "WARNING: Make sure to use the ModuleTracer plugin before running this tool." << std::endl << std::endl; } if (trace.hasItems() == false ) { traceFile << "WARNING: No basic blocks in the path " << std::dec << *listit << std::endl; traceFile << "WARNING: Make sure to use the TranslationBlockTracer plugin before running this tool. " << std::endl << std::endl; } TestCaseState *tcs = static_cast<TestCaseState*>(pb.getState(&tc, *pit)); if (!tcs) { traceFile << "WARNING: No test case in the path " << std::dec << *listit << std::endl; traceFile << "WARNING: Make sure to use the TestCaseGenerator plugin and terminate the states before running this tool. " << std::endl << std::endl; }else { tcs->printInputs(traceFile); } } }
//A flat trace has only one path void LogParser::getPaths(PathSet &s) { s.clear(); s.insert(0); }
void PfProfiler::process() { uint64_t maxMissCount=0, maxMissPath=0; uint64_t maxICount=0, maxICountPath=0; uint64_t minMissCount=(uint64_t)-1, minMissPath=0; uint64_t minICount=(uint64_t)-1, minICountPath=0; std::ofstream statsFile; statsFile.open(CpOutFile.c_str()); if (TerminatedPaths) { statsFile << "#This report shows data for only those paths that generated a test case" << std::endl; } PathBuilder pb(&m_Parser); m_Parser.parse(m_FileName); ModuleCache mc(&pb); CacheProfiler cp(&mc, &pb); TestCase tc(&pb); InstructionCounter ic(&pb); pb.processTree(); unsigned pathNum = 0; PathSet paths; pb.getPaths(paths); PathSet::iterator pit; for(pit = paths.begin(); pit != paths.end(); ++pit) { statsFile << "========== Path " << pathNum << " ========== "<<std::endl; std::cout << std::dec << "Path " << pathNum << std::endl; TestCaseState *tcs = static_cast<TestCaseState*>(pb.getState(&tc, *pit)); InstructionCounterState *ics = static_cast<InstructionCounterState*>(pb.getState(&ic, *pit)); if (TerminatedPaths) { if (!tcs || !tcs->hasInputs()) { pathNum++; continue; } } if (ics) { ics->printCounter(statsFile); }else { statsFile << "No instruction count in the trace file for the current path" << std::endl; } if (tcs) { tcs->printInputs(statsFile); }else { statsFile << "No test case in the trace file for the current path" << std::endl; } TopMissesPerModule tmpm(&m_binaries, &cp); tmpm.setFilteredProcess(CPFilterProcess); tmpm.setFilteredModule(FilterModule); tmpm.setMinMissThreshold(CPMinMissCountFilter); tmpm.computeStats(*pit); statsFile << "Total misses on this path: " << std::dec << tmpm.getTotalMisses() << std::endl; tmpm.printAggregatedStatistics(statsFile); tmpm.print(statsFile); if (ics) { if (ics->getCount() > maxICount) { maxICount = ics->getCount(); maxICountPath = pathNum; } if (ics->getCount() < minICount) { minICount = ics->getCount(); minICountPath = pathNum; } } if (tmpm.getTotalMisses() > maxMissCount) { maxMissCount = tmpm.getTotalMisses(); maxMissPath = pathNum; } if (tmpm.getTotalMisses() < minMissCount) { minMissCount = tmpm.getTotalMisses(); minMissPath = pathNum; } ++pathNum; statsFile << std::endl; } statsFile << "----------------------------------" << std::endl << std::dec; statsFile << "Miss count - Max:" << std::setw(10) << maxMissCount << " (path " << std::setw(10) << maxMissPath << ") "; statsFile << "Min:" << std::setw(10)<< minMissCount << "(path " << std::setw(10) << minMissPath << ")" << std::endl; statsFile << "Instruction count - Max:" << std::setw(10) << maxICount << " (path "<< std::setw(10) << maxICountPath << ") "; statsFile << "Min:"<< std::setw(10) << minICount << "(path " << std::setw(10) << minICountPath << ")" << std::endl; return; }
void PfProfiler::extractAggregatedData() { std::ofstream statsFile; std::string sFile = OutDir + "/pf.stats"; statsFile.open(sFile.c_str()); if (TerminatedPaths) { statsFile << "#This report shows data for only those paths that generated a test case" << std::endl; } if (FilterModule.size() > 0) { statsFile << "#PageFaults and TlbMisses for module " << FilterModule << std::endl; } statsFile << "#Path TestCase PageFaults TlbMisses ICount" << std::endl; PathBuilder pb(&m_Parser); m_Parser.parse(m_FileName); TestCase tc(&pb); ModuleCache mc(&pb); InstructionCounter ic(&pb); PageFault pf(&pb, &mc); if (FilterModule.size() > 0) { pf.setModule(FilterModule); } pb.processTree(); PathSet paths; pb.getPaths(paths); PathSet::iterator pit; for(pit = paths.begin(); pit != paths.end(); ++pit) { PageFaultState *pfs = static_cast<PageFaultState*>(pb.getState(&pf, *pit)); TestCaseState *tcs = static_cast<TestCaseState*>(pb.getState(&tc, *pit)); InstructionCounterState *ics = static_cast<InstructionCounterState*>(pb.getState(&ic, *pit)); if (TerminatedPaths) { if (!tcs || !tcs->hasInputs()) { continue; } } statsFile << std::dec << *pit << "\t"; if (tcs) { statsFile << "yes" << "\t"; }else { statsFile << "no" << "\t"; } if (!pfs) { statsFile << std::dec << "-" << "\t"; statsFile << std::dec << "-" << "\t"; } else { statsFile << std::dec << pfs->getPageFaults() << "\t"; statsFile << pfs->getTlbMisses() << "\t"; } if (!ics) { statsFile << std::dec << "-" << "\t"; } else { statsFile << std::dec << ics->getCount() << "\t"; } statsFile << std::endl; } }