Component* ComponentSet::find(const std::string &name) const { ComponentSet *nonConstThis = const_cast<ComponentSet*>(this); ComponentMap::iterator i = nonConstThis->components_.find(name); if (i != components_.end()) { ComponentContainer &cont = i->second; if (!isComponentLoaded(name)) { nonConstThis->sendOnLoad(name, cont); } return cont.component; } return NULL; }
void TrueTimeSourceVisitor::Visit_QualifiedMessageStructure( const QualifiedMessage & qualifiedMessage, const Semantics::Task & task ) { // Get the actual message object Semantics::Msg message = qualifiedMessage.message; // Create a new section for it AddSectionDictionary( "MESSAGE_SECTION" ); // Get the message name std::string messageName = message.name(); // Figure out non-dotted name string::size_type pos = messageName.find("."); if ( pos != string::npos ) messageName.replace( pos, 1, "_" ); DEBUGOUT( "\tMessage: " << messageName << std::endl ); std::string messageType = message.messagetype(); GetTemplateDictionary().SetValue( "MESSAGE_NAME", messageName ); // Get the associated signals SignalSet signalSet = message.carries(); SignalSet::iterator signalIter = signalSet.begin(); SortedSignal_ByMsgIndex_Set filteredSignalSet; // Loop through all signals for( ; signalIter != signalSet.end() ; signalIter++ ) { std::string signalName = signalIter->name(); ComponentSet receivingComponentSet = signalIter->consumedBy(); Semantics::Component transmittingComponent = signalIter->generatedBy(); // Check to make sure for something?!?!?!?!? if ( qualifiedMessage.type == TRANSMIT && receivingComponentSet.empty() || qualifiedMessage.type == RECEIVE && transmittingComponent == Udm::null || qualifiedMessage.type == PERIPHERAL ) { // Insert the signal into the sorted set filteredSignalSet.insert( *signalIter ); } } // Use the constructed sorted signal set to fill in the template SortedSignal_ByMsgIndex_Set::iterator filteredSignalIter = filteredSignalSet.begin(); for ( ; filteredSignalIter != filteredSignalSet.end(); filteredSignalIter++ ) { Visit_Signal_Member( *filteredSignalIter ); } // Finish up with this section PopSectionDictionary(); // See if message is remote if ( messageType.compare( "Remote" ) == 0 ) { Semantics::CommMedium cm = GetMessageBus( message ); string busName = "bus"; if ( cm != Udm::null ) { busName = cm.name(); } AddSectionDictionary( "BUSMESSAGE_SECTION" ); string msgTaskName = messageName + "_task"; GetTemplateDictionary().SetValue( "BUSMESSAGE_NAME", msgTaskName ); GetTemplateDictionary().SetValue( "BUSMESSAGE_FULLNAME", messageName ); GetTemplateDictionary().SetValue( "BUSMESSAGE_FUNCTION", messageName + "_code" ); // Get the exec info and schedule ExecInfoSet execInfoSet = message.info(); ExecInfoSet::iterator execInfoIter = execInfoSet.begin(); Semantics::Duration duration = execInfoIter->Duration_child(); double wcet = duration.exectimesecs(); string wcet_symbol = msgTaskName + "_WCET"; ostringstream out1; out1 << "#define " << wcet_symbol << " " << wcet; _BusHeaderLines[busName].insert( out1.str() ); GetTemplateDictionary().SetValue( "BUSMESSAGE_WCET_STR", wcet_symbol ); GetTemplateDictionary().SetFormattedValue( "BUSMESSAGE_WCET", "%f", wcet ); // Setup the peripheral schedule Semantics::Schedule schedule = execInfoIter->Schedule_child(); std::string sched = schedule.sched(); int count = sched_count( sched ); vector< double > start_times = sched_values( sched ); ostringstream symbolic_array; for ( int idx = 0; idx < count; idx++ ) { ostringstream out2; out2 << "#define " << msgTaskName << "_" << idx << " " << start_times[idx]; _BusHeaderLines[busName].insert( out2.str() ); if ( idx > 0 ) { symbolic_array << ", "; } symbolic_array << msgTaskName << "_" << idx; } GetTemplateDictionary().SetIntValue( "BUSMESSAGE_COUNT", count ); GetTemplateDictionary().SetValue( "BUSMESSAGE_SCHEDULE", symbolic_array.str() ); // Get the network that transmits the message ReceivesSet receiveSet = message.msgListeners(); // TODO: Need to figure out how to disambiguate receivers for this message Semantics::BChan bChan = receiveSet.begin()->receivingChannel(); Semantics::CommInterface commInterface = bChan.chanInterface(); Semantics::CommMedium network = commInterface.commMedium(); // Find the network in the map std::map< std::string, TTNetwork >::const_iterator mapIter = _networkMap.find( network.name() ); // Setup the message handling code Semantics::Transmits transmitter = message.msgTransmitter(); Semantics::Task sendingTask = transmitter.sendingTask(); // See if this task is being sent or received if ( sendingTask == task ) { // Add the appropriate section AddSectionDictionary( "BUSMESSAGE_SEND" ); // Loop on all receivers ReceivesSet::iterator receivesIter = receiveSet.begin(); for ( ; receivesIter != receiveSet.end(); receivesIter++ ) { AddSectionDictionary( "BUSMESSAGE_SENDBLOCK" ); // Which node is receiving Semantics::Task task = receivesIter->receivingTask(); Semantics::Node node = task.executedBy(); // Find the node in the mapIter std::map< std::string, int >::iterator nodeIter = mapIter->second.nodes->find( node.name() ); // Set the network GetTemplateDictionary().SetIntValue( "BUSMESSAGE_NETWORK", mapIter->second.id ); // Set the receiver GetTemplateDictionary().SetIntValue( "BUSMESSAGE_RECEIVER", nodeIter->second ); // Done with this send block PopSectionDictionary(); } // Done with the BUSMESSAGE_SEND PopSectionDictionary(); } // Must be receiving else { // Add the appropriate section AddSectionDictionary( "BUSMESSAGE_RECEIVE" ); // Set the network ID GetTemplateDictionary().SetIntValue( "BUSMESSAGE_NETWORK", mapIter->second.id ); // Done with this section PopSectionDictionary(); } PopSectionDictionary(); } }
void TrueTimeSourceVisitor::Visit_Task( const Semantics::Task &task ) { // Get the task name std::string taskName = task.name(); DEBUGOUT( "\tTask: " << taskName << std::endl ); // Process messages for this task QualifiedMessageSet messageSet = GetQualifiedMessages( task ); QualifiedMessageSet::iterator messageIter = messageSet.begin(); for ( ; messageIter != messageSet.end() ; messageIter++ ) { // Visit the message to generate template section Visit_QualifiedMessageStructure( *messageIter, task ); } // Get the exec info and schedule ExecInfoSet execInfoSet = task.info(); ExecInfoSet::iterator execInfoIter = execInfoSet.begin(); Semantics::Duration duration = execInfoIter->Duration_child(); double wcet = duration.exectimesecs(); // Add a section for the task execution AddSectionDictionary( "TASK_SECTION" ); string wcet_symbol = taskName + "_WCET"; GetTemplateDictionary().SetValue( "TASK_WCET_STR", wcet_symbol ); GetTemplateDictionary().SetFormattedValue( "TASK_WCET", "%f", wcet ); ostringstream out1; out1 << "#define " << wcet_symbol << " " << wcet; _SchedHeaderLines.push_back( out1.str() ); // Setup the peripheral schedule Semantics::Schedule schedule = execInfoIter->Schedule_child(); std::string sched = schedule.sched(); int count = sched_count( sched ); vector< double > start_times = sched_values( sched ); ostringstream symbolic_array; for ( int idx = 0; idx < count; idx++ ) { ostringstream out2; out2 << "#define " << taskName << "_" << idx << " " << start_times[idx]; _SchedHeaderLines.push_back( out2.str() ); if ( idx > 0 ) { symbolic_array << ", "; } symbolic_array << taskName << "_" << idx; } GetTemplateDictionary().SetIntValue( "TASK_COUNT", count ); //GetTemplateDictionary().SetValue( "TASK_SCHEDULE", sched ); GetTemplateDictionary().SetValue( "TASK_SCHEDULE", symbolic_array.str() ); // Get the set of components this task invokes ComponentSet componentSet = task.invokes(); // If there are components... if ( !componentSet.empty() ) { // Start with the first component Semantics::Component component = *componentSet.begin(); // Get the component name std::string compName = component.name(); GetTemplateDictionary().SetValue( "TASK_NAME", compName + "_task" ); GetTemplateDictionary().SetValue( "TASK_FUNCTION", compName + "_code" ); // Create the list of component header files StringList headerList = Split( component.cfiles() ); StringList::iterator headerIter = headerList.begin(); // Iterate through the list for( ; headerIter != headerList.end() ; headerIter++ ) { if ( _already_included.find( *headerIter ) == _already_included.end() ) { // Include a header section and populate it AddSectionDictionary( "TASK_INCLUDE" ); GetTemplateDictionary().SetValue( "TASK_HEADER", *headerIter ); PopSectionDictionary(); _already_included.insert( *headerIter ); } } // Set the component function name GetTemplateDictionary().SetValue( "TASK_COMPNAME", compName ); std::string compMSubsys = component.msubsystem(); // Account for GetTemplateDictionary().SetValue( "TASK_MSUBSYS", compMSubsys ); // Setup the input signals to the component SortedSignal_ByCallIndex_Set inputSignalSet = component.consumes_sorted( SignalCallIndexSorter() ); SortedSignal_ByCallIndex_Set::iterator inputIter = inputSignalSet.begin() ; for( ; inputIter != inputSignalSet.end(); inputIter++ ) { AddSectionDictionary( "INPUT_SIGNALS" ); Visit_Signal( *inputIter ); PopSectionDictionary(); } // Setup the output signals to the component SortedSignal_ByCallIndex_Set outputSignalSet = component.generates_sorted( SignalCallIndexSorter() ); SortedSignal_ByCallIndex_Set::iterator outputIter = outputSignalSet.begin(); for ( ; outputIter != outputSignalSet.end(); outputIter++ ) { AddSectionDictionary( "OUTPUT_SIGNALS" ); Visit_Signal( *outputIter ); PopSectionDictionary(); } } // Done with section dictionary PopSectionDictionary(); }
void EvalHeuristicEasy::build(EvalGraphBuilder& builder) { ComponentGraph& compgraph = builder.getComponentGraph(); bool didSomething; do { didSomething = false; // // forall external components e: // merge with all rules that // * depend on e // * do not contain external atoms // * do not depend on something e does not (transitively) depend on // { ComponentIterator cit; // do not use boost::tie here! the container is modified in the loop! for(cit = compgraph.getComponents().first; cit != compgraph.getComponents().second; ++cit) { Component comp = *cit; if( compgraph.propsOf(comp).outerEatoms.empty() ) continue; LOG(ANALYZE,"checking whether to collapse external component " << comp << " with successors"); // get predecessors ComponentSet preds; transitivePredecessorComponents(compgraph, comp, preds); // get successors ComponentSet collapse; bool addedToCollapse; // do this as long as we find new ones // if we do not do this loop, we might miss something // as PredecessorIterator not necessarily honours topological order // (TODO this could be made more efficient) do { addedToCollapse = false; ComponentGraph::SuccessorIterator sit, sit_end; for(boost::tie(sit, sit_end) = compgraph.getProvides(comp); sit != sit_end; ++sit) { Component succ = compgraph.sourceOf(*sit); // skip successors with eatoms if( !compgraph.propsOf(succ).outerEatoms.empty() ) continue; // do not check found stuff twice if( collapse.find(succ) != collapse.end() ) continue; DBGLOG(DBG,"found successor " << succ); ComponentGraph::PredecessorIterator pit, pit_end; bool good = true; for(boost::tie(pit, pit_end) = compgraph.getDependencies(succ); pit != pit_end; ++pit) { Component dependson = compgraph.targetOf(*pit); if( preds.find(dependson) == preds.end() ) { LOG(DBG,"successor bad as it depends on other node " << dependson); good = false; break; } } if( good ) { // collapse with this collapse.insert(succ); preds.insert(succ); addedToCollapse = true; } } } while(addedToCollapse); // collapse if not nonempty if( !collapse.empty() ) { collapse.insert(comp); Component c = compgraph.collapseComponents(collapse); LOG(ANALYZE,"collapse of " << printrange(collapse) << " yielded new component " << c); // restart loop after collapse cit = compgraph.getComponents().first; didSomething = true; } } } // // forall components with only inner rules or constraints: // merge with children that are no eatoms and do not depend on anything else // { ComponentIterator cit = compgraph.getComponents().first; while(cit != compgraph.getComponents().second) { Component comp = *cit; if( !compgraph.propsOf(comp).outerEatoms.empty() ) { cit++; continue; } LOG(ANALYZE,"checking whether to collapse internal-only component " << comp << " with children"); // get successors ComponentSet collapse; ComponentGraph::SuccessorIterator sit, sit_end; for(boost::tie(sit, sit_end) = compgraph.getProvides(comp); sit != sit_end; ++sit) { Component succ = compgraph.sourceOf(*sit); // skip successors with eatoms if( !compgraph.propsOf(succ).outerEatoms.empty() ) continue; DBGLOG(DBG,"found successor " << succ); ComponentGraph::PredecessorIterator pit, pit_end; boost::tie(pit, pit_end) = compgraph.getDependencies(succ); bool good = true; assert(pit != pit_end); if( compgraph.targetOf(*pit) != comp ) { LOG(DBG,"successor bad as it depends on other node " << compgraph.targetOf(*pit)); good = false; } pit++; if( pit != pit_end ) { good = false; LOG(DBG,"successor bad as it depends on more nodes"); } if( good ) collapse.insert(succ); } if( !collapse.empty() ) { // collapse! (decreases graph size) collapse.insert(comp); assert(collapse.size() > 1); Component c = compgraph.collapseComponents(collapse); LOG(ANALYZE,"collapse of " << printrange(collapse) << " yielded new component " << c); // restart loop after collapse cit = compgraph.getComponents().first; didSomething = true; } else { // advance ++cit; } } } // // forall components with only inner rules or constraints: // merge with components that depend on exactly the same predecessors // { ComponentIterator cit = compgraph.getComponents().first; while(cit != compgraph.getComponents().second) { Component comp = *cit; if( !compgraph.propsOf(comp).outerEatoms.empty() ) { cit++; continue; } LOG(ANALYZE,"checking whether to collapse internal-only component " << comp << " with others"); ComponentSet collapse; // get direct predecessors ComponentSet preds; { ComponentGraph::PredecessorIterator pit, pit_end; for(boost::tie(pit, pit_end) = compgraph.getDependencies(comp); pit != pit_end; ++pit) { preds.insert(compgraph.targetOf(*pit)); } } if( preds.empty() ) { // do not combine stuff that depends only on edb cit++; continue; } // compare all further ones (further because of symmetry breaking) ComponentIterator cit2 = cit; cit2++; while( cit2 != compgraph.getComponents().second ) { Component comp2 = *cit2; DBGLOG(DBG,"checking other component " << comp2); ComponentSet preds2; { ComponentGraph::PredecessorIterator pit, pit_end; for(boost::tie(pit, pit_end) = compgraph.getDependencies(comp2); pit != pit_end; ++pit) { preds2.insert(compgraph.targetOf(*pit)); } } if( preds2 == preds ) collapse.insert(comp2); cit2++; } if( !collapse.empty() ) { // collapse! (decreases graph size) collapse.insert(comp); assert(collapse.size() > 1); Component c = compgraph.collapseComponents(collapse); LOG(ANALYZE,"collapse of " << printrange(collapse) << " yielded new component " << c); // restart loop after collapse cit = compgraph.getComponents().first; didSomething = true; } else { // advance ++cit; } } } // // forall components with only inner constraints: // merge with all other constraint-only components // if(false) { ComponentSet collapse; ComponentIterator cit; // do not use boost::tie here! the container is modified in the loop! for(cit = compgraph.getComponents().first; cit != compgraph.getComponents().second; ++cit) { Component comp = *cit; if( compgraph.propsOf(comp).outerEatoms.empty() && compgraph.propsOf(comp).innerRules.empty() ) collapse.insert(comp); } if( !collapse.empty() ) { // collapse! (decreases graph size) LOG(ANALYZE,"collapsing constraint-only nodes " << printrange(collapse)); Component c = compgraph.collapseComponents(collapse); didSomething = true; } } } while(didSomething); // // create eval units using topological sort // ComponentContainer sortedcomps; evalheur::topologicalSortComponents(compgraph.getInternalGraph(), sortedcomps); LOG(ANALYZE,"now creating evaluation units from components " << printrange(sortedcomps)); for(ComponentContainer::const_iterator it = sortedcomps.begin(); it != sortedcomps.end(); ++it) { // just create a unit from each component (we collapsed above) std::list<Component> comps; comps.push_back(*it); std::list<Component> ccomps; EvalGraphBuilder::EvalUnit u = builder.createEvalUnit(comps, ccomps); LOG(ANALYZE,"component " << *it << " became eval unit " << u); } }