SignalSet SignalInformationQueue::getQueuedSignalSet() const { SignalSet queuedSignalSet {SignalSet::empty}; for (const auto& node : signalInformationList_) queuedSignalSet.add(node.signalInformation.getSignalNumber()); return queuedSignalSet; }
bool signalsTestSelfOneSignalPending(const uint8_t signalNumber) { SignalSet expectedSignalSet {SignalSet::empty}; if (expectedSignalSet.add(signalNumber) != 0) return false; return ThisThread::Signals::getPendingSignalSet().getBitset() == expectedSignalSet.getBitset(); }
std::pair<int, SignalAction> SignalsCatcherControlBlock::setAssociation(const uint8_t signalNumber, const SignalAction& signalAction) { if (signalNumber >= SignalSet::Bitset{}.size()) return {EINVAL, {}}; if (signalAction.getHandler() == SignalAction{}.getHandler()) // default handler is being set? { const auto previousSignalAction = clearAssociation(signalNumber); return {{}, previousSignalAction}; } const auto numberAssociation = findAssociation(associationsBegin_, associationsEnd_, signalNumber); const auto actionAssociation = findAssociation(associationsBegin_, associationsEnd_, signalAction); if (actionAssociation != associationsEnd_) // there is an association for this SignalAction? { if (numberAssociation == actionAssociation) // no change? return {{}, signalAction}; actionAssociation->first.add(signalNumber); const auto previousSignalAction = numberAssociation != associationsEnd_ ? clearAssociation(signalNumber, *numberAssociation) : SignalAction{}; return {{}, previousSignalAction}; } // there is no association for this SignalAction? SignalSet signalSet {1u << signalNumber}; // there is no storage for new association if all conditions are true: // - there are no free associations, // - no Association object was found for signal number or Association object found for signal number has more // than one signal number associated. if (std::distance(storageBegin_, storageEnd_) == 0 && (numberAssociation == associationsEnd_ || numberAssociation->first.getBitset() != signalSet.getBitset())) return {EAGAIN, {}}; const auto previousSignalAction = numberAssociation != associationsEnd_ ? clearAssociation(signalNumber, *numberAssociation) : SignalAction{}; if (storageBegin_ == storageEnd_) abort(); /// \todo replace with assertion new (associationsEnd_) Association{signalSet, signalAction}; ++associationsEnd_; return {{}, previousSignalAction}; }
SignalDispatcher(const Args&... args) : _signal_set(_io_service, SIGINT, SIGTERM) , _thread(new std::thread(std::bind((IoServiceRunFunc)&IoService::run, &_io_service))) { std::size_t size = sizeof...(args); StopHandle res[sizeof...(args)] = {args...}; auto stop_func = [size, res] () { for (std::uint32_t i = 0; i < size; ++i) { res[i](); } LOG(INFO) << "Stop modules."; }; _signal_set.async_wait(std::bind(stop_func)); _thread->join(); }
void SignalThread::run_(const SignalSet& sigset) { // boost::asio has support for signals via signal_set. It does however not // accept a sigset_t and neither can a sigset_t nor a ba::signal_set be inspected. int sigfd = signalfd(-1, &sigset.sigset(), SFD_NONBLOCK); if (sigfd < 0) { LOG_ERROR("Failed to create signalfd: " << strerror(errno)); throw Exception("Failed to create signalfd"); } auto exit(make_scope_exit([&] { close(sigfd); })); std::function<void()> g; auto f([&](const bs::error_code& ec, std::size_t bytes) { VERIFY(bytes == 0); if (ec) { LOG_ERROR("error in signal handler: " << ec.message()); } else { signalfd_siginfo si; ssize_t ret = ::read(sigfd, &si, sizeof(si)); if (ret < 0) { if (ret != EAGAIN) { ret = errno; LOG_ERROR("failed to read siginfo from signalfd: " << strerror(ret) << " (" << ret << ")"); } g(); } else if (ret != sizeof(si)) { LOG_ERROR("read less (" << ret << " ) than expected (" << sizeof(si) << ") from signalfd"); } else { LOG_INFO("caught signal " << si.ssi_signo); handler_(si.ssi_signo); g(); } } }); ba::posix::stream_descriptor sigdesc(io_service_, sigfd); g = [&]() { sigdesc.async_read_some(ba::null_buffers(), f); }; g(); bs::error_code ec; io_service_.run(ec); if (ec) { LOG_ERROR("error running I/O service of signal thread: " << ec.message()); }; LOG_INFO("exiting signal handler thread"); }
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(); } }