本文整理汇总了C++中Cfg类的典型用法代码示例。如果您正苦于以下问题:C++ Cfg类的具体用法?C++ Cfg怎么用?C++ Cfg使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Cfg类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: mm
PrologEpilogGenerator::PrologEpilogGenerator(Cfg &cfg) :
mm(cfg.getMM()),
cfg(cfg),
outRegArgs(mm),
prologInsts(mm),
epilogInsts(mm),
allocInsts(mm),
saveSpInsts(mm),
savePfsInsts(mm),
saveUnatInsts(mm),
saveGrsInsts(mm),
saveFrsInsts(mm),
saveBrsInsts(mm),
savePrsInsts(mm),
saveRpInsts(mm),
restRpInsts(mm),
restPrsInsts(mm),
restBrsInsts(mm),
restFrsInsts(mm),
restGrsInsts(mm),
restUnatInsts(mm),
restPfsInsts(mm),
restSpInsts(mm),
epilogNodes(mm) {
opndManager = cfg.getOpndManager();
p0 = opndManager->getP0();
sp = opndManager->getR12();
stackAddr = opndManager->newRegOpnd(OPND_G_REG, DATA_I64, SPILL_REG1);
}
示例2: getId2Node
Graph* Connector::connect(Graph* g)
{
const std::vector<CfgNode*>& nodes = g->getNodes();
std::map<unsigned int, CfgNode*> id2node = getId2Node(nodes);
for (unsigned int i = 0; i < nodes.size(); i++) {
CfgNode* fromNode = nodes[i];
Cfg* cfg = fromNode->getCfg();
std::vector<unsigned int> nexts = cfg->getNext();
for (unsigned int j = 0; j < nexts.size(); j++) {
CfgNode* toNode = id2node[nexts[j]];
if (toNode == NULL)
THROWEXCEPTION("next statement is illegal; there is no node with id=%d", nexts[j]);
if (connectNodes) // insert the connection in the graph
g->addEdge(fromNode, toNode);
msg(MSG_INFO, "Connecting module %s[Id = %d] -> %s[Id = %d]",
cfg->getName().c_str(), cfg->getID(),
id2node[nexts[j]]->getCfg()->getName().c_str(),
id2node[nexts[j]]->getCfg()->getID());
if (connectModules) {// connect the modules
DPRINTF("connecting instances");
cfg->connectInstances(toNode->getCfg());
}
}
}
return g;
}
示例3: MakeCode
static Handle<Code> MakeCode(FunctionLiteral* literal,
Handle<Script> script,
Handle<Context> context,
bool is_eval) {
ASSERT(literal != NULL);
// Rewrite the AST by introducing .result assignments where needed.
if (!Rewriter::Process(literal) || !AnalyzeVariableUsage(literal)) {
// Signal a stack overflow by returning a null handle. The stack
// overflow exception will be thrown by the caller.
return Handle<Code>::null();
}
{
// Compute top scope and allocate variables. For lazy compilation
// the top scope only contains the single lazily compiled function,
// so this doesn't re-allocate variables repeatedly.
HistogramTimerScope timer(&Counters::variable_allocation);
Scope* top = literal->scope();
while (top->outer_scope() != NULL) top = top->outer_scope();
top->AllocateVariables(context);
}
#ifdef DEBUG
if (Bootstrapper::IsActive() ?
FLAG_print_builtin_scopes :
FLAG_print_scopes) {
literal->scope()->Print();
}
#endif
// Optimize the AST.
if (!Rewriter::Optimize(literal)) {
// Signal a stack overflow by returning a null handle. The stack
// overflow exception will be thrown by the caller.
return Handle<Code>::null();
}
if (FLAG_multipass) {
CfgGlobals scope(literal);
Cfg* cfg = Cfg::Build();
#ifdef DEBUG
if (FLAG_print_cfg && cfg != NULL) {
SmartPointer<char> name = literal->name()->ToCString();
PrintF("Function \"%s\":\n", *name);
cfg->Print();
PrintF("\n");
}
#endif
if (cfg != NULL) {
return cfg->Compile(script);
}
}
// Generate code and return it.
Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval);
return result;
}
示例4: ssa_cfg_to_instr_list
/*
* ssa_cfg_to_instr_list -- First restore conventional (non-SSA form).
* Then convert the resulting CFG to InstrList form, delete the now-empty
* CFG, and return the instruction list.
*/
InstrList*
ssa_cfg_to_instr_list(SsaCfg *ssa_cfg)
{
Cfg *cfg = restore(ssa_cfg);
InstrList *instr_list = cfg->to_instr_list();
delete cfg;
return instr_list;
}
示例5: main
int main(int argc, char * argv[]){
remove("tmp/test1.txt");
remove("tmp/test2.txt");
remove("./tmp/graph.dot");
if (argc < 2) {
cout << "erreur : pas de fichier assembleur en entrée" << endl;
}
Program prog(argv[1]);
Function* functmp;
list <Basic_block*> myBB;
cout<<"Le programme a "<<prog.size()<<" lignes\n"<<endl;
cout<<"Contenu du programme:"<<endl;
//prog.display();
prog.in_file("tmp/restit.txt");
cout<<"\n Calcul des fonctions des block de base et restitution\n"<<endl;
prog.comput_function();
cout<<"nombre de fonction: "<<prog.nbr_func()<<endl;
Cfg *graph;
for (int i=0; i<prog.nbr_func(); i++){
functmp= prog.get_function(i);
if(functmp==NULL){
cout<<"null"<<endl;
break;
}
// functmp->restitution("tmp/test1.txt");
functmp->comput_basic_block();
functmp->comput_label();
for(int j=0; j<functmp->nbr_BB(); j++){
//functmp->get_BB(j)->display();
}
functmp->comput_succ_pred_BB();
graph =new Cfg(functmp->get_BB(0),
functmp->nbr_BB());
cout<<"------------Function "<< (i+1) <<"/"<<prog.nbr_func()<<" DISPLAY----------\n" <<endl;
//functmp->test();
graph->display(NULL);
}
// graph->restitution(NULL,"./tmp/graph.dot");
}
示例6: CPPUNIT_ASSERT
void CfgTest::testSemiDominators ()
{
BinaryFileFactory bff;
BinaryFile* pBF = bff.Load(SEMI_PENTIUM);
CPPUNIT_ASSERT(pBF != 0);
Prog* prog = new Prog;
FrontEnd* pFE = new PentiumFrontEnd(pBF, prog, &bff);
Type::clearNamedTypes();
prog->setFrontEnd(pFE);
pFE->decode(prog);
bool gotMain;
ADDRESS addr = pFE->getMainEntryPoint(gotMain);
CPPUNIT_ASSERT (addr != NO_ADDRESS);
UserProc* pProc = (UserProc*) prog->getProc(0);
Cfg* cfg = pProc->getCFG();
DataFlow* df = pProc->getDataFlow();
df->dominators(cfg);
// Find BB "L (6)" (as per Appel, Figure 19.8).
BB_IT it;
PBB bb = cfg->getFirstBB(it);
while (bb && bb->getLowAddr() != SEMI_L)
{
bb = cfg->getNextBB(it);
}
CPPUNIT_ASSERT(bb);
int nL = df->pbbToNode(bb);
// The dominator for L should be B, where the semi dominator is D
// (book says F)
unsigned actual_dom = (unsigned)df->nodeToBB(df->getIdom(nL))->getLowAddr();
unsigned actual_semi = (unsigned)df->nodeToBB(df->getSemi(nL))->getLowAddr();
CPPUNIT_ASSERT_EQUAL((unsigned)SEMI_B, actual_dom);
CPPUNIT_ASSERT_EQUAL((unsigned)SEMI_D, actual_semi);
// Check the final dominator frontier as well; should be M and B
std::ostringstream expected, actual;
//expected << std::hex << SEMI_M << " " << SEMI_B << " ";
expected << std::hex << SEMI_B << " " << SEMI_M << " ";
std::set<int>::iterator ii;
std::set<int>& DFset = df->getDF(nL);
for (ii=DFset.begin(); ii != DFset.end(); ii++)
actual << std::hex << (unsigned)df->nodeToBB(*ii)->getLowAddr() << " ";
CPPUNIT_ASSERT_EQUAL(expected.str(), actual.str());
delete pFE;
}
示例7: lockGraph
void ConfigManager::shutdown()
{
lockGraph();
std::vector<CfgNode*> topoNodes = graph->topoSort();
// shutdown modules
for (size_t i = 0; i < topoNodes.size(); i++) {
Cfg* cfg = topoNodes[i]->getCfg();
msg(MSG_INFO, "shutting down module %s (id=%u)", cfg->getName().c_str(), cfg->getID());
cfg->shutdown(true, true);
}
// trigger sensorManager to get the final statistics of this Vermont run
if (sensorManager) {
sensorManager->retrieveStatistics(true);
}
// disconnect the modules
for (size_t i = 0; i < topoNodes.size(); i++) {
CfgNode* n = topoNodes[i];
Cfg* cfg = n->getCfg();
// disconnect the module from its sources ..
vector<CfgNode*> sources = graph->getSources(n);
msg(MSG_INFO, "disconnecting module %s (id=%u)", cfg->getName().c_str(), cfg->getID());
for (size_t k = 0; k < sources.size(); k++) {
sources[k]->getCfg()->disconnectInstances();
}
}
unlockGraph();
}
示例8: readCfg
void readCfg(Cfg& config, const string& cfg)
{
xmlDocPtr config_doc = xmlParseFile(cfg.c_str());
if(config_doc == NULL) {
throw string("missing configuration file ")+cfg;
}
config.ReConfigure(config_doc->children);
xmlFreeDoc(config_doc);
}
示例9: assert
/*==============================================================================
* FUNCTION: createReturnBlock
* OVERVIEW: Create a Return or a Oneway BB if a return statement already exists
* PARAMETERS: pProc: pointer to enclosing UserProc
* BB_rtls: list of RTLs for the current BB (not including pRtl)
* pRtl: pointer to the current RTL with the semantics for the return statement (including a
* ReturnStatement as the last statement)
* RETURNS: Pointer to the newly created BB
*============================================================================*/
PBB FrontEnd::createReturnBlock(UserProc* pProc, std::list<RTL*>* BB_rtls, RTL* pRtl) {
Cfg* pCfg = pProc->getCFG();
PBB pBB;
// Add the RTL to the list; this has the semantics for the return instruction as well as the ReturnStatement
// The last Statement may get replaced with a GotoStatement
if (BB_rtls == NULL) BB_rtls = new std::list<RTL*>; // In case no other semantics
BB_rtls->push_back(pRtl);
ADDRESS retAddr = pProc->getTheReturnAddr();
std::cout << "retAddr = " << std::hex << retAddr << " rtl = " <<std::hex<< pRtl->getAddress() << "\n";
// LOG << "retAddr = " << retAddr << " rtl = " << pRtl->getAddress() << "\n";
if (retAddr == NO_ADDRESS) {
// Create the basic block
pBB = pCfg->newBB(BB_rtls, RET, 0);
Statement* s = pRtl->getList().back(); // The last statement should be the ReturnStatement
pProc->setTheReturnAddr((ReturnStatement*)s, pRtl->getAddress());
} else {
// We want to replace the *whole* RTL with a branch to THE first return's RTL. There can sometimes be extra
// semantics associated with a return (e.g. Pentium return adds to the stack pointer before setting %pc and
// branching). Other semantics (e.g. SPARC returning a value as part of the restore instruction) are assumed to
// appear in a previous RTL. It is assumed that THE return statement will have the same semantics (NOTE: may
// not always be valid). To avoid this assumption, we need branches to statements, not just to native addresses
// (RTLs).
PBB retBB = pProc->getCFG()->findRetNode();
assert(retBB);
if (retBB->getFirstStmt()->isReturn()) {
// ret node has no semantics, clearly we need to keep ours
pRtl->deleteLastStmt();
} else
pRtl->clear();
pRtl->appendStmt(new GotoStatement(retAddr));
try {
pBB = pCfg->newBB(BB_rtls, ONEWAY, 1);
// if BB already exists but is incomplete, exception is thrown
pCfg->addOutEdge(pBB, retAddr, true);
// Visit the return instruction. This will be needed in most cases to split the return BB (if it has other
// instructions before the return instruction).
targetQueue.visit(pCfg, retAddr, pBB);
} catch(Cfg::BBAlreadyExistsError &) {
if (VERBOSE)
LOG << "not visiting " << retAddr << " due to exception\n";
}
}
return pBB;
}
示例10: QDialog
Configuration::Configuration( QWidget *parent, Cfg &cfg )
: QDialog( parent, 0, TRUE, WStyle_ContextHelp )
{
setCaption( tr( "Configure Checkbook" ) );
// Setup layout to make everything pretty
QVBoxLayout *layout = new QVBoxLayout( this );
layout->setMargin( 2 );
layout->setSpacing( 4 );
// Setup tabs for all info
_mainWidget = new QTabWidget( this );
layout->addWidget( _mainWidget );
// Settings tab
_mainWidget->addTab( initSettings(cfg), tr( "&Settings" ) );
// Account Types tab
ColumnDef *d;
_listEditTypes=new ListEdit(_mainWidget, "TYPES" );
d=new ColumnDef( tr("Type"), (ColumnDef::ColumnType)(ColumnDef::typeString | ColumnDef::typeUnique), tr("New Account Type"));
_listEditTypes->addColumnDef( d );
_listEditTypes->addData( cfg.getAccountTypes() );
_mainWidget->addTab( _listEditTypes, tr( "&Account Types" ) );
// Categories tab
_listEditCategories=new ListEdit(_mainWidget, "CATEGORIES" );
_listEditCategories->addColumnDef( new ColumnDef( tr("Category"), (ColumnDef::ColumnType)(ColumnDef::typeString | ColumnDef::typeUnique), tr("New Category")) );
d=new ColumnDef( tr("Type"), ColumnDef::typeList, tr("Expense") );
d->addColumnValue( tr("Expense") );
d->addColumnValue( tr("Income") );
_listEditCategories->addColumnDef( d );
QStringList lst=cfg.getCategories();
_listEditCategories->addData( lst );
_mainWidget->addTab( _listEditCategories, tr( "&Categories" ) );
// Payees tab
_listEditPayees=new ListEdit(_mainWidget, "PAYEES");
_listEditPayees->addColumnDef( new ColumnDef( tr("Payee"), (ColumnDef::ColumnType)(ColumnDef::typeString | ColumnDef::typeUnique), tr("New Payee")) );
_listEditPayees->addData( cfg.getPayees() );
_mainWidget->addTab( _listEditPayees, tr("&Payees") );
}
示例11: get_post_cfgs
std::vector<Cfg> tmr::post(const Cfg& cfg, unsigned short tid, MemorySetup msetup) {
// execute low-level action
auto post = get_post_cfgs(cfg, tid, msetup);
#define RETURN return post;
// check for high-level simulation
#if REPLACE_INTERFERENCE_WITH_SUMMARY
assert(msetup == PRF);
assert(tid == 0);
// initial and summaries do not need a summary
auto& stmt = *cfg.pc[tid];
if (ignore_for_summary(stmt)) {
RETURN;
}
// find those post cfgs that require a summary, i.e. that changed the shared heap
auto require_summaries = find_effectful_configurations(cfg, post);
if (require_summaries.size() == 0) {
RETURN;
}
// frees shall have an empty summary
if (stmt.clazz() == Statement::FREE) {
// if a free comes that far, we are in trouble as it requires a non-empty summary
throw std::runtime_error("Misbehaving Summary: free stmt requires non-empty summary.");
}
// prepare summary
Cfg tmp = cfg.copy();
tmp.pc[tid] = &stmt.function().summary();
if (stmt.function().has_output()) tmp.inout[tid] = OValue();
// execute summary
auto sumpost = get_post_cfgs(tmp, tid, msetup);
// check summary
for (const Cfg& postcfg : require_summaries) {
bool covered = false;
for (const Cfg& summarycfg : sumpost) {
if (subset_shared(postcfg, summarycfg)) {
covered = true;
break;
}
}
if (!covered) throw std::runtime_error("Misbehaving Summary: failed to mimic low-level action.");
}
#endif
RETURN;
}
示例12: saveConfig
// --- saveConfig -------------------------------------------------------------
void Configuration::saveConfig(Cfg &cfg)
{
// Settings
cfg.setCurrencySymbol( symbolEdit->text() );
cfg.setUseSmallFont( smallFontCB->isChecked() );
cfg.setShowLocks( lockCB->isChecked() );
cfg.setShowBalances( balCB->isChecked() );
cfg.setOpenLastBook( openLastBookCB->isChecked() );
cfg.setShowLastTab( lastTabCB->isChecked() );
cfg.setSavePayees( savePayees->isChecked() );
// Typelist
_listEditTypes->storeInList( cfg.getAccountTypes() );
// Category list
QStringList lst;
_listEditCategories->storeInList( lst );
cfg.setCategories( lst );
// Payees
_listEditPayees->storeInList( cfg.getPayees() );
}
示例13: GetPackageManifest
PackageInfo PackageManager::GetPackageManifest(const Cfg& cfg, const string& packageId, const std::string& texmfPrefix)
{
auto key = cfg.GetKey(packageId);
if (key == nullptr)
{
MIKTEX_UNEXPECTED();
}
PackageInfo packageInfo;
packageInfo.id = packageId;
for (auto val : *key)
{
if (val->GetName() == "displayName")
{
packageInfo.displayName = val->AsString();
}
else if (val->GetName() == "creator")
{
packageInfo.creator = val->AsString();
}
else if (val->GetName() == "title")
{
packageInfo.title = val->AsString();
}
else if (val->GetName() == "version")
{
packageInfo.version = val->AsString();
}
else if (val->GetName() == "targetSystem")
{
packageInfo.targetSystem = val->AsString();
}
else if (val->GetName() == "description[]")
{
packageInfo.description = std::for_each(val->begin(), val->end(), Flattener('\n')).result;
}
else if (val->GetName() == "require[]")
{
packageInfo.requiredPackages = val->AsStringVector();
}
else if (val->GetName() == "runSize")
{
packageInfo.sizeRunFiles = Utils::ToSizeT(val->AsString());
}
else if (val->GetName() == "run[]")
{
for (const string& s : *val)
{
PathName path(s);
#if defined(MIKTEX_UNIX)
path.ConvertToUnix();
#endif
if (texmfPrefix.empty() || (PathName::Compare(texmfPrefix, path, texmfPrefix.length()) == 0))
{
packageInfo.runFiles.push_back(path.ToString());
}
}
}
else if (val->GetName() == "docSize")
{
packageInfo.sizeDocFiles = Utils::ToSizeT(val->AsString());
}
else if (val->GetName() == "doc[]")
{
for (const string& s : *val)
{
PathName path(s);
#if defined(MIKTEX_UNIX)
path.ConvertToUnix();
#endif
if (texmfPrefix.empty() || (PathName::Compare(texmfPrefix, path, texmfPrefix.length()) == 0))
{
packageInfo.docFiles.push_back(path.ToString());
}
}
}
else if (val->GetName() == "sourceSize")
{
packageInfo.sizeSourceFiles = Utils::ToSizeT(val->AsString());
}
else if (val->GetName() == "source[]")
{
for (const string& s : *val)
{
PathName path(s);
#if defined(MIKTEX_UNIX)
path.ConvertToUnix();
#endif
if (texmfPrefix.empty() || (PathName::Compare(texmfPrefix, path, texmfPrefix.length()) == 0))
{
packageInfo.sourceFiles.push_back(path.ToString());
}
}
}
else if (val->GetName() == "timePackaged")
{
packageInfo.timePackaged = Utils::ToTimeT(val->AsString());
}
else if (val->GetName() == "digest")
{
packageInfo.digest = MD5::Parse(val->AsString());
//.........这里部分代码省略.........
示例14: BinaryFileStub
void FrontSparcTest::testDelaySlot() {
BinaryFileFactory bff;
BinaryFile *pBF = bff.Load(BRANCH_SPARC);
if (pBF == NULL)
pBF = new BinaryFileStub(); // fallback on stub
CPPUNIT_ASSERT(pBF != 0);
CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_SPARC);
Prog* prog = new Prog;
FrontEnd *pFE = new SparcFrontEnd(pBF, prog, &bff);
prog->setFrontEnd(pFE);
// decode calls readLibraryCatalog(), which needs to have definitions for non-sparc architectures cleared
Type::clearNamedTypes();
pFE->decode(prog);
bool gotMain;
ADDRESS addr = pFE->getMainEntryPoint(gotMain);
CPPUNIT_ASSERT (addr != NO_ADDRESS);
std::string name("testDelaySlot");
UserProc* pProc = new UserProc(prog, name, addr);
std::ofstream dummy;
bool res = pFE->processProc(addr, pProc, dummy, false);
CPPUNIT_ASSERT(res == 1);
Cfg* cfg = pProc->getCFG();
BB_IT it;
PBB bb = cfg->getFirstBB(it);
std::ostringstream o1;
bb->print(o1);
std::string expected("Call BB:\n"
"in edges: \n"
"out edges: 10a98 \n"
"00010a80 0 *32* tmp := r14 - 120\n"
" 0 *32* m[r14] := r16\n"
" 0 *32* m[r14 + 4] := r17\n"
" 0 *32* m[r14 + 8] := r18\n"
" 0 *32* m[r14 + 12] := r19\n"
" 0 *32* m[r14 + 16] := r20\n"
" 0 *32* m[r14 + 20] := r21\n"
" 0 *32* m[r14 + 24] := r22\n"
" 0 *32* m[r14 + 28] := r23\n"
" 0 *32* m[r14 + 32] := r24\n"
" 0 *32* m[r14 + 36] := r25\n"
" 0 *32* m[r14 + 40] := r26\n"
" 0 *32* m[r14 + 44] := r27\n"
" 0 *32* m[r14 + 48] := r28\n"
" 0 *32* m[r14 + 52] := r29\n"
" 0 *32* m[r14 + 56] := r30\n"
" 0 *32* m[r14 + 60] := r31\n"
" 0 *32* r24 := r8\n"
" 0 *32* r25 := r9\n"
" 0 *32* r26 := r10\n"
" 0 *32* r27 := r11\n"
" 0 *32* r28 := r12\n"
" 0 *32* r29 := r13\n"
" 0 *32* r30 := r14\n"
" 0 *32* r31 := r15\n"
" 0 *32* r14 := tmp\n"
"00010a84 0 *32* r16 := 0x11400\n"
"00010a88 0 *32* r16 := r16 | 808\n"
"00010a8c 0 *32* r8 := r16\n"
"00010a90 0 *32* tmp := r30\n"
" 0 *32* r9 := r30 - 20\n"
"00010a90 0 CALL scanf(\n"
" )\n"
" Reaching definitions: \n"
" Live variables: \n");
std::string actual(o1.str());
CPPUNIT_ASSERT_EQUAL(expected, actual);
bb = cfg->getNextBB(it);
CPPUNIT_ASSERT(bb);
std::ostringstream o2;
bb->print(o2);
expected = std::string("Call BB:\n"
"in edges: 10a90 \n"
"out edges: 10aa4 \n"
"00010a98 0 *32* r8 := r16\n"
"00010a9c 0 *32* tmp := r30\n"
" 0 *32* r9 := r30 - 24\n"
"00010a9c 0 CALL scanf(\n"
" )\n"
" Reaching definitions: \n"
" Live variables: \n");
actual = std::string(o2.str());
CPPUNIT_ASSERT_EQUAL(expected, actual);
bb = cfg->getNextBB(it);
CPPUNIT_ASSERT(bb);
std::ostringstream o3;
bb->print(o3);
expected = std::string("Twoway BB:\n"
"in edges: 10a9c \n"
"out edges: 10ac8 10ab8 \n"
"00010aa4 0 *32* r8 := m[r30 - 20]\n"
"00010aa8 0 *32* r16 := 5\n"
"00010aac 0 *32* tmp := r16\n"
//.........这里部分代码省略.........
示例15: msg
Graph* ConfigManager::reconnect(Graph* g, Graph *old)
{
Graph *newGraph;
Graph *oldGraph;
newGraph = g;
oldGraph = old;
vector<CfgNode*> topoOld = oldGraph->topoSort();
vector<CfgNode*> topoNew = newGraph->topoSort();
/* disconnect all modules */
for (size_t i = 0; i < topoOld.size(); i++) {
topoOld[i]->getCfg()->getInstance()->preReconfiguration();
topoOld[i]->getCfg()->disconnectInstances();
msg(MSG_INFO, "Disconnecting instance: %s", topoOld[i]->getCfg()->getName().c_str());
}
/* call onReconfiguration1 on all modules */
for (size_t i = 0; i < topoOld.size(); i++) {
topoOld[i]->getCfg()->onReconfiguration1();
}
/* call preConfiguration2 on all modules */
for (size_t i = 0; i < topoOld.size(); i++) {
topoOld[i]->getCfg()->onReconfiguration2();
}
// compare the nodes in the old and new graph and search for
// (nearly) identical modules which could be reused
for (size_t i = 0; i < topoOld.size(); i++) {
Cfg* oldCfg = topoOld[i]->getCfg();
for (size_t j = 0; j < topoNew.size(); j++) {
Cfg* newCfg = topoNew[j]->getCfg();
if (oldCfg->getID() == newCfg->getID()) { // possible match
msg(MSG_INFO, "found a match between %s(id=%d) -> %s(id=%d)",
oldCfg->getName().c_str(), oldCfg->getID(),
newCfg->getName().c_str(), newCfg->getID());
// check if we could use the same module instance in the new config
if (newCfg->deriveFrom(oldCfg)) {
msg(MSG_INFO, "reusing %s(id=%d)",
oldCfg->getName().c_str(), oldCfg->getID());
newCfg->transferInstance(oldCfg);
} else {
deleter_list_item delme;
delme.c = oldCfg;
delme.delete_after = time(NULL) + DELETER_DELAY; // current time + 20 seconds
deleter_list.push_back(delme);
msg(MSG_INFO, "can't reuse %s(id=%d)",
oldCfg->getName().c_str(), oldCfg->getID());
}
}
}
}
/* Now that we transfered all module instances which could be reused
* into the new graph, we have to build up the new connections
*
* The Connector will take care to call preConnect for us!!!
*/
Connector con(false, true);
newGraph->accept(&con);
return newGraph;
}