void const_graph_visitort::graph_explore_BC(event_grapht& egraph, unsigned next, std::list<unsigned>& old_path, std::set<unsigned>& edges, bool porw) { /* TODO: restricts to C_1 U ... U C_n for perf improvement */ assert(old_path.size() > 0); fence_inserter.instrumenter.message.debug() << "(BC) explore " << old_path.front() << " --...--> " << next << messaget::eom; if(visited_nodes.find(next)!=visited_nodes.end()) return; visited_nodes.insert(next); /* if all the incoming pos were already visited, add */ bool no_other_pos = true; for(graph<abstract_eventt>::edgest::const_iterator it= egraph.po_out(next).begin(); it!=egraph.po_out(next).end(); ++it) if(visited_nodes.find(it->first)==visited_nodes.end()) { no_other_pos = false; break; } if(egraph.po_out(next).size()==0 || no_other_pos) { /* inserts all the pos collected from old_path in edges */ std::list<unsigned>::const_iterator it=old_path.begin(); std::list<unsigned>::const_iterator next_it=it; ++next_it; for(;next_it!=old_path.end() && it!=old_path.end(); ++it, ++next_it) { const abstract_eventt& e1=egraph[*it]; const abstract_eventt& e2=egraph[*next_it]; if(!porw || (e1.operation==abstract_eventt::Read && e2.operation==abstract_eventt::Write)) edges.insert(fence_inserter.add_edge(edget(*it,*next_it))); } assert(it!=old_path.end()); } else { for(graph<abstract_eventt>::edgest::const_iterator next_it=egraph.po_out(next).begin(); next_it!=egraph.po_out(next).end(); ++next_it) { old_path.push_back/*front*/(next_it->first); graph_explore_BC(egraph, next_it->first, old_path, edges); old_path.pop_back/*front*/(); } } }
/// \par parameters: e in comWR /\ C_j (invisible variables) /// \return e's in po /\ C (problem variables) void const_graph_visitort::CT( const edget &edge, std::set<unsigned> &edges) { event_grapht &egraph=fence_inserter.instrumenter.egraph; /* the edge can be in the reversed order (back-edge) */ const abstract_eventt &test_first=egraph[edge.first]; const abstract_eventt &test_second=egraph[edge.second]; assert(test_first.operation!=test_second.operation); const event_idt first= (test_first.operation==abstract_eventt::operationt::Write? edge.first: edge.second); const event_idt second= (test_second.operation==abstract_eventt::operationt::Read? edge.second: edge.first); /* TODO: AC + restricts to C_1 U ... U C_n */ visited_nodes.clear(); /* if one event only on this thread of the cycle, discard */ if(!egraph.po_in(first).empty()) { for(wmm_grapht::edgest::const_iterator next_it=egraph.po_in(first).begin(); next_it!=egraph.po_in(first).end(); ++next_it) { std::list<event_idt> new_path; new_path.push_back(first); new_path.push_back(next_it->first); graph_explore_AC(egraph, next_it->first, new_path, edges); } } if(!egraph.po_out(second).empty()) { for(wmm_grapht::edgest::const_iterator next_it=egraph.po_out(second).begin(); next_it!=egraph.po_out(second).end(); ++next_it) { std::list<event_idt> new_path; new_path.push_back(second); new_path.push_back(next_it->first); graph_explore_BC(egraph, next_it->first, new_path, edges); } } }
void const_graph_visitort::CT_not_powr(const edget& edge, std::set<unsigned>& edges) { event_grapht& egraph=fence_inserter.instrumenter.egraph; /* the edge can be in the reversed order (back-edge) */ const abstract_eventt& test_first=egraph[edge.first]; const abstract_eventt& test_second=egraph[edge.second]; assert(test_first.operation!=test_second.operation); const unsigned first= (test_first.operation==abstract_eventt::Write?edge.first:edge.second); const unsigned second= (test_second.operation==abstract_eventt::Read?edge.second:edge.first); /* TODO: AC + restricts to C_1 U ... U C_n */ visited_nodes.clear(); if(egraph.po_in(first).size() > 0) for(graph<abstract_eventt>::edgest::const_iterator next_it=egraph.po_in(first).begin(); next_it!=egraph.po_in(first).end(); ++next_it) { std::list<unsigned> new_path; new_path.push_back(first); new_path.push_back(next_it->first); graph_explore_AC(egraph, next_it->first, new_path, edges, true); } if(egraph.po_out(second).size() > 0) for(graph<abstract_eventt>::edgest::const_iterator next_it=egraph.po_out(second).begin(); next_it!=egraph.po_out(second).end(); ++next_it) { std::list<unsigned> new_path; new_path.push_back(second); new_path.push_back(next_it->first); graph_explore_BC(egraph, next_it->first, new_path, edges, true); } }