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();
}
Esempio n. 4
0
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);
    }
}