Page MenuHomePhorge

No OneTemporary

Size
27 KB
Referenced Files
None
Subscribers
None
diff --git a/examples/deluxe-interface/deluxe-interface.cpp b/examples/deluxe-interface/deluxe-interface.cpp
index 896f555..43222e4 100755
--- a/examples/deluxe-interface/deluxe-interface.cpp
+++ b/examples/deluxe-interface/deluxe-interface.cpp
@@ -1,191 +1,191 @@
//===-- examples/deluxe-interface/deluxe-interface.cpp ----------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file examples/deluxe-interface/deluxe-interface.cpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017
///
/// \brief A simple example on the \c rosa::deluxe::DeluxeContext and related
/// classes.
//===----------------------------------------------------------------------===//
#include "rosa/config/version.h"
#include "rosa/deluxe/DeluxeContext.hpp"
#include <algorithm>
#include <cmath>
#include <vector>
using namespace rosa;
using namespace rosa::deluxe;
using namespace rosa::terminal;
/// How many cycles of simulation to perform.
const size_t NumberOfSimulationCycles = 16;
/// Helper function creating a deluxe agent for logging and forwarding values.
///
/// Received values are dumped to \c LOG_INFO_STREAM and then returned as
/// result.
///
/// \tparam T type of values to handle
///
/// \param C the deluxe context to create the agent in
/// \param Name name of the new agent
///
/// \return handle for the new agent
template <typename T>
AgentHandle createLowLevelAgent(std::unique_ptr<DeluxeContext> &C,
const std::string &Name) {
using handler = DeluxeAgent::D<T, T>;
using result = Optional<T>;
return C->createAgent(
Name, handler([&, Name](std::pair<T, bool> I) -> result {
LOG_INFO_STREAM << "\n******\n"
<< Name << " " << (I.second ? "<New>" : "<Old>")
<< " value: " << I.first << "\n******\n";
return {I.first};
}));
}
int main(void) {
LOG_INFO_STREAM << '\n'
<< library_string() << " -- " << Color::Red
<< "deluxe-interface example" << Color::Default << '\n';
std::unique_ptr<DeluxeContext> C = DeluxeContext::create("Deluxe");
//
// Create deluxe sensors.
//
LOG_INFO("Creating sensors.");
// All sensors are created without defining a normal generator function, but
// with the default value of the second argument. That, however, requires the
// data type to be explicitly defined. This is good for simulation only.
AgentHandle IntSensor = C->createSensor<int32_t>("IntSensor");
AgentHandle FloatSensor = C->createSensor<float>("FloatSensor");
// Check and set execution policy for sensors.
LOG_INFO("Execution policies for sensors.");
- LOG_INFO(C->getExecutionPolicy(IntSensor)->dump());
+ LOG_INFO(std::to_string(*C->getExecutionPolicy(IntSensor)));
C->setExecutionPolicy(IntSensor, DeluxeExecutionPolicy::decimation(2));
C->setExecutionPolicy(FloatSensor, DeluxeExecutionPolicy::decimation(2));
- LOG_INFO(C->getExecutionPolicy(IntSensor)->dump());
+ LOG_INFO(std::to_string(*C->getExecutionPolicy(IntSensor)));
//
// Create low-level deluxe agents with \c createLowLevelAgent.
//
LOG_INFO("Creating low-level agents.");
AgentHandle IntAgent = createLowLevelAgent<int32_t>(C, "IntAgent");
AgentHandle FloatAgent = createLowLevelAgent<float>(C, "FloatAgent");
// Set execution policies for low-level agents.
LOG_INFO("Setting Execution policies for low-level agents.");
C->setExecutionPolicy(IntAgent, DeluxeExecutionPolicy::awaitAll({0}));
C->setExecutionPolicy(FloatAgent, DeluxeExecutionPolicy::awaitAll({0}));
//
// Connect sensors to low-level agents.
//
LOG_INFO("Connect sensors to their corresponding low-level agents.");
C->connectSensor(IntAgent, 0, IntSensor, "Int Sensor Channel");
C->connectSensor(FloatAgent, 0, FloatSensor, "Float Sensor Channel");
//
// Create a high-level deluxe agent.
//
LOG_INFO("Create high-level agent.");
// The new agent logs its input values and results in the the sum of them.
AgentHandle SumAgent = C->createAgent(
"Sum Agent", DeluxeAgent::D<double, int32_t, float>(
[](std::pair<int32_t, bool> I1,
std::pair<float, bool> I2) -> Optional<double> {
LOG_INFO_STREAM
<< "\n*******\nSum Agent triggered with values:\n"
<< (I1.second ? "<New>" : "<Old>")
<< " int value: " << I1.first << "\n"
<< (I2.second ? "<New>" : "<Old>")
<< " float value: " << I2.first << "\n******\n";
return {I1.first + I2.first};
}));
//
// Connect low-level agents to the high-level agent.
//
LOG_INFO("Connect low-level agents to the high-level agent.");
C->connectAgents(SumAgent, 0, IntAgent, "Int Agent Channel");
C->connectAgents(SumAgent, 1, FloatAgent, "Float Agent Channel");
//
// For simulation output, create a logger agent writing the output of the
// high-level agent into a log stream.
//
LOG_INFO("Create a logger agent.");
// The agent logs each new input value and produces nothing.
AgentHandle LoggerAgent =
C->createAgent("Logger Agent",
DeluxeAgent::D<unit_t, double>(
[](std::pair<double, bool> Sum) -> Optional<unit_t> {
if (Sum.second) {
LOG_INFO_STREAM << "Result: " << Sum.first << "\n";
}
return {};
}));
//
// Connect the high-level agent to the logger agent.
//
LOG_INFO("Connect the high-level agent to the logger agent.");
C->connectAgents(LoggerAgent, 0, SumAgent, "Sum Agent Channel");
//
// Do simulation.
//
LOG_INFO("Setting up and performing simulation.");
//
// Initialize deluxe context for simulation.
//
C->initializeSimulation();
//
// Create some vectors and register them for their corresponding sensors.
//
std::vector<int32_t> IntValues(NumberOfSimulationCycles);
std::generate(IntValues.begin(), IntValues.end(),
[i = 0](void) mutable { return ++i; });
C->registerSensorValues(IntSensor, IntValues.begin(), IntValues.end());
std::vector<float> FloatValues(NumberOfSimulationCycles);
std::generate(FloatValues.begin(), FloatValues.end(),
[f = 0.5f](void) mutable {
f += 0.3f;
return std::floor(f) + 0.5f;
});
C->registerSensorValues(FloatSensor, FloatValues.begin(), FloatValues.end());
//
// Simulate.
//
C->simulate(NumberOfSimulationCycles);
return 0;
}
diff --git a/include/rosa/deluxe/DeluxeExecutionPolicy.h b/include/rosa/deluxe/DeluxeExecutionPolicy.h
index ffbe353..6daa713 100644
--- a/include/rosa/deluxe/DeluxeExecutionPolicy.h
+++ b/include/rosa/deluxe/DeluxeExecutionPolicy.h
@@ -1,175 +1,195 @@
//===-- rosa/deluxe/DeluxeExecutionPolicy.h ---------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/deluxe/DeluxeExecutionPolicy.h
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Public interface of *execution policies* in the *deluxe interface*.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_DELUXE_DELUXEEXECUTIONPOLICY_H
#define ROSA_DELUXE_DELUXEEXECUTIONPOLICY_H
#include "rosa/core/AgentHandle.hpp"
#include <memory>
+#include <ostream>
#include <set>
#include <vector>
namespace rosa {
namespace deluxe {
// Forward declaration of DeluxeSystem. Do not include the corresponding header
// in this file because of cyclic dependency.
class DeluxeSystem;
/// *Execution policy* that controls how *agents* and *sensors* call their
/// processing functions.
///
/// An *execution policy* can be applied to a deluxe *unit* only if \c
/// deluxe::rosa::DeluxeExecutionPolicy::canHandle() allows it. Each deluxe
/// *unit* must have a compatible *execution policy* associated to it, and the
/// *unit* queries \c rosa::deluxe::DeluxeExecutionPolicy::doExecute() on each
/// triggering and calls its processing funtion only if it is allowed by the
/// *execution policy*.
///
/// \see rosa::deluxe::DeluxeExecutionPolicy::decimation()
/// \see rosa::deluxe::DeluxeExecutionPolicy::awaitAll()
/// \see rosa::deluxe::DeluxeExecutionPolicy::awaitAny()
///
/// \todo Extend the interface with query functions about what kind of
/// execution policy is behind the interface. This can be done in relation
/// to the existing factory functions; for example, if the actual object is
/// decimation and with what rate.
class DeluxeExecutionPolicy {
protected:
/// Protected constructor, only implementations can instantiate the class.
DeluxeExecutionPolicy(void) noexcept = default;
private:
/// No instance can be copy-constructed, move-constructed, copied, and moved.
///
///@{
DeluxeExecutionPolicy(const DeluxeExecutionPolicy &) = delete;
DeluxeExecutionPolicy(DeluxeExecutionPolicy &&) = delete;
DeluxeExecutionPolicy &operator=(const DeluxeExecutionPolicy &) = delete;
DeluxeExecutionPolicy &operator=(DeluxeExecutionPolicy &&) = delete;
///@}
public:
/// Virtual destructor for subclasses.
virtual ~DeluxeExecutionPolicy(void) noexcept = default;
/// Creates an *execution policy* that allows execution with decimation of
/// triggering.
///
//// *Decimation* can handle both *agents* and *sensors*.
/// Processing functions are executed only on every \p D <sup>th</sup>
/// triggering. In the case of *sensors* in simulation, the simulation data
/// source is read on each triggering as it provides values with respect to
/// the highest execution frequency, but output is generated by the *sensor*
/// only on every \p D <sup>th</sup> triggering.
///
/// \note A rate of \c 0 is allowed as actual argument and is treated as rate
/// \c 1 (i.e., execute processing functions on each triggering).
///
/// \param D the rate of *decimation*
///
/// \return an *execution policy* implementing *decimation* with rate \p D
static std::unique_ptr<DeluxeExecutionPolicy> decimation(const size_t D);
/// Creates an *execution policy* that allows execution only if all defined
/// *slave* positions has new input.
///
/// *Await all* can handle only *agents* and only if the particular *agent*
/// has at least as many *slave* positions as the largest position defined in
/// \p S. Processing functions are executed only if new input has been
/// received for all defined *slave* positions.
///
/// \param S set of *slave* positions to await input from
///
/// \return an *execution policy* implementing *awaiting all* input from set
/// \p S
static std::unique_ptr<DeluxeExecutionPolicy>
awaitAll(const std::set<size_t> &S);
/// Creates an *execution policy* that allows execution if any of the defined
/// *slave* positions has new input.
///
/// *Await any* can handle only *agents* and only if the particular *agent*
/// has at least as many *slave* positions as the largest position defined in
/// \p S. Processing functions are executed if new input has been received for
/// any of the defined *slave* positions.
///
/// \param S set of *slave* positions to await input from
///
/// \return an *execution policy* implementing *awaiting any* input from set
/// \p S
static std::unique_ptr<DeluxeExecutionPolicy>
awaitAny(const std::set<size_t> &S);
/// Tells if \p this object can handle the deluxe *unit* referred by \p H.
///
/// The *execution policy* implemented by \p this object is applicable to the
/// given deluxe *unit* referred by \p H only if the function returns \c true.
///
/// \param H reference to the *unit* to check
/// \param S the system owning the *unit* referred by \p H
///
/// \return if \p this object can handle the *unit* referred by \p H
virtual bool canHandle(const AgentHandle H, const DeluxeSystem &S) const
noexcept = 0;
/// Tells if processing function should be executed on the current triggering.
///
/// The function is to be called on each triggering of the deluxe *unit*.
/// Decision about execution of processing function is done by \p this object
/// according to the implemented *execution policy*.
///
/// \param InputChanged flags indicating whether new input has been received
/// at *slave* positions
///
/// \return if to execute processing function
virtual bool doExecute(const std::vector<bool> &InputChanged) noexcept = 0;
/// Dumps \p this object into textual representation.
///
/// \return textual representation of \p this object
virtual std::string dump(void) const noexcept = 0;
protected:
/// Tells whether the *unit* referred by \p H is a \c
/// rosa::deluxe::DeluxeAgent.
///
/// \param H reference to the *unit* to check
/// \param S the system owning the *unit* referred by \p H
///
/// \return if the *unit* referred by \p H is a \c rosa::deluxe::DeluxeAgent
bool isDeluxeAgent(const AgentHandle H, const DeluxeSystem &S) const noexcept;
/// Tells the number of inputs handled by the *unit* referred by \p H.
///
/// If \p H refers to a \c rosa::deluxe::DeluxeAgent, the function returns the
/// number of inputs (i.e., *slave* positions) of the *agent*. Otherwise, the
/// function returns \c 0.
///
/// \param H reference to the *unit* to check
/// \param S the system owning the *unit* referred by \p H
///
/// \return the number of inputs handled by the *unit* referred by \p H
size_t numberOfDeluxeAgentInputs(const AgentHandle H,
const DeluxeSystem &S) const noexcept;
};
} // End namespace deluxe
} // End namespace rosa
+namespace std {
+
+/// Converts a \c rosa::deluxe::DeluxeExecutionPolicy into \c std::string.
+///
+/// \param EP \c rosa::deluxe::DeluxeExecutionPolicy to convert
+///
+/// \return \c std::string representing \p EP
+string to_string(const rosa::deluxe::DeluxeExecutionPolicy &EP);
+
+/// Dumps a \c rosa::deluxe::DeluxeExecutionPolicy to a given \c std::ostream.
+///
+/// \param [in,out] OS output stream to dump to
+/// \param EP \c rosa::deluxe::DeluxeExecutionPolicy to dump
+///
+/// \return \p OS after dumping \p EP to it
+ostream &operator<<(ostream &OS, const rosa::deluxe::DeluxeExecutionPolicy &EP);
+
+} // End namespace std
+
#endif // ROSA_DELUXE_DELUXEEXECUTIONPOLICY_H
diff --git a/lib/deluxe/DeluxeAgent.cpp b/lib/deluxe/DeluxeAgent.cpp
index 3728913..0096b02 100755
--- a/lib/deluxe/DeluxeAgent.cpp
+++ b/lib/deluxe/DeluxeAgent.cpp
@@ -1,233 +1,238 @@
//===-- deluxe/DeluxeAgent.cpp ----------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file deluxe/DeluxeAgent.cpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief Implementation of rosa/deluxe/DeluxeAgent.hpp.
///
//===----------------------------------------------------------------------===//
#include "rosa/deluxe/DeluxeAgent.hpp"
#include "rosa/deluxe/DeluxeSystem.hpp"
#include <algorithm>
namespace rosa {
namespace deluxe {
bool DeluxeAgent::inv(void) const noexcept {
// Check execution policy.
// \note The \c rosa::System the \c rosa::Unit is created with is a
// \c rosa::DeluxeSystem.
const DeluxeSystem &DS = static_cast<DeluxeSystem &>(Unit::system());
if (!ExecutionPolicy || !ExecutionPolicy->canHandle(Self, DS)) {
return false;
}
// Check container sizes.
if (!(InputTypes.size() == NumberOfInputs &&
InputChanged.size() == NumberOfInputs &&
InputValues->size() == NumberOfInputs &&
Slaves.size() == NumberOfInputs)) {
return false;
}
// Check *slave* types and validate *slave* registrations and reverse lookup
// information.
std::map<id_t, size_t> RefIds; // Build up a reference of SlaveIds in this.
for (size_t I = 0; I < NumberOfInputs; ++I) {
// First, validate input types at position \c I.
const TypeNumber T = InputTypes[I];
if (InputValues->typeAt(I) != T) {
return false;
}
// Check the registered *slave* at position \c I.
const auto &Slave = Slaves[I];
// If \c Slave is empty, nothing to check.
if (!Slave)
continue;
// \c Slave is not empty here.
// Check the `OutputType` of the registered *slave*.
const auto &A = unwrapAgent(*Slave);
if (!((A.Kind == atoms::SensorKind &&
static_cast<const DeluxeSensor &>(A).OutputType == T) ||
(A.Kind == atoms::AgentKind &&
static_cast<const DeluxeAgent &>(A).OutputType == T))) {
return false;
}
// Validate that the *slave* is not registered more than once.
if (std::any_of(
Slaves.begin() + I + 1, Slaves.end(),
[&Slave](const Optional<AgentHandle> &O) { return O && *Slave == *O; })) {
return false;
}
// Build the content of \c RefIds.
RefIds.emplace(A.Id, I);
}
// Validate *slave* reverse lookup information against our reference.
if (RefIds != SlaveIds) {
return false;
}
// All checks were successful, the invariant is held.
return true;
}
DeluxeAgent::~DeluxeAgent(void) noexcept {
ASSERT(inv());
LOG_TRACE("Destroying DeluxeAgent...");
// Make sure \p this object is not a registered *slave*.
if (Master) {
ASSERT(unwrapAgent(*Master).Kind == atoms::AgentKind); // Sanity check.
DeluxeAgent &M = static_cast<DeluxeAgent&>(unwrapAgent(*Master));
ASSERT(M.positionOfSlave(self()) != M.NumberOfInputs); // Sanity check.
M.registerSlave(M.positionOfSlave(self()), {});
Master = {};
}
// Also, make sure \p this object is no acting *master*.
for (size_t Pos = 0; Pos < NumberOfInputs; ++Pos) {
registerSlave(Pos, {});
}
// Now there is no connection with other entities, safe to destroy.
}
const DeluxeExecutionPolicy &DeluxeAgent::executionPolicy(void) const noexcept {
ASSERT(inv());
return *ExecutionPolicy;
}
bool DeluxeAgent::setExecutionPolicy(
std::unique_ptr<DeluxeExecutionPolicy> &&EP) noexcept {
ASSERT(inv());
+ LOG_TRACE_STREAM << "DeluxeAgent " << FullName << " setting execution policy "
+ << *EP << std::endl;
bool Success = false;
// \note The \c rosa::System the \c rosa::Unit is created with is a
// \c rosa::DeluxeSystem.
const DeluxeSystem &DS = static_cast<DeluxeSystem &>(Unit::system());
if (EP && EP->canHandle(self(), DS)) {
ExecutionPolicy.swap(EP);
Success = true;
+ } else {
+ LOG_TRACE_STREAM << "Execution policy " << *EP
+ << " cannot handle DeluxeAgent " << FullName << std::endl;
}
ASSERT(inv());
return Success;
}
Optional<AgentHandle> DeluxeAgent::master(void) const noexcept {
ASSERT(inv());
return Master;
}
void DeluxeAgent::registerMaster(const Optional<AgentHandle> _Master) noexcept {
ASSERT(inv() && (!_Master || unwrapAgent(*_Master).Kind == atoms::AgentKind));
Master = _Master;
ASSERT(inv());
}
TypeNumber DeluxeAgent::inputType(const size_t Pos) const noexcept {
ASSERT(inv() && Pos < NumberOfInputs);
return InputTypes[Pos];
}
Optional<AgentHandle> DeluxeAgent::slave(const size_t Pos) const noexcept {
ASSERT(inv() && Pos < NumberOfInputs);
return Slaves[Pos];
}
void DeluxeAgent::registerSlave(const size_t Pos,
const Optional<AgentHandle> Slave) noexcept {
ASSERT(inv() && Pos < NumberOfInputs &&
(!Slave ||
(unwrapAgent(*Slave).Kind == atoms::SensorKind &&
static_cast<const DeluxeSensor &>(unwrapAgent(*Slave)).OutputType ==
InputTypes[Pos]) ||
(unwrapAgent(*Slave).Kind == atoms::AgentKind &&
static_cast<const DeluxeAgent &>(unwrapAgent(*Slave)).OutputType ==
InputTypes[Pos])));
// If registering an actual *slave*, not just clearing the slot, make sure
// the same *slave* is not registered to another slot.
if (Slave) {
auto It = SlaveIds.find(unwrapAgent(*Slave).Id);
if (It != SlaveIds.end()) {
Slaves[It->second] = {};//Optional<AgentHandle>();
SlaveIds.erase(It);
}
}
// Obtain the place whose content is to be replaced with \p Slave
auto &OldSlave = Slaves[Pos];
// If there is already a *slave* registered at \p Pos, clear reverse lookup
// information for it, and make sure it no longer has \p this object as
// *master*.
if (OldSlave) {
auto &A = unwrapAgent(*OldSlave);
ASSERT(SlaveIds.find(A.Id) != SlaveIds.end()); // Sanity check.
SlaveIds.erase(A.Id);
if (A.Kind == atoms::AgentKind) {
static_cast<DeluxeAgent &>(A).registerMaster({});
} else {
ASSERT(A.Kind == atoms::SensorKind); // Sanity check.
static_cast<DeluxeSensor &>(A).registerMaster({});
}
}
// Register \p Slave at \p Pos.
OldSlave = Slave;
// If registering an actual *slave*, not just clearing the slot, register
// reverse lookup information for the new *slave*.
if (Slave) {
SlaveIds.emplace(unwrapAgent(*Slave).Id, Pos);
}
ASSERT(inv());
}
size_t DeluxeAgent::positionOfSlave(const AgentHandle Slave) const noexcept {
ASSERT(inv());
bool Found = false;
size_t Pos = 0;
while (!Found && Pos < NumberOfInputs) {
auto &ExistingSlave = Slaves[Pos];
if (ExistingSlave && *ExistingSlave == Slave) {
Found = true;
} else {
++Pos;
}
}
ASSERT(Found || Pos == NumberOfInputs); // Sanity check.
return Pos;
}
void DeluxeAgent::handleTrigger(atoms::Trigger) noexcept {
ASSERT(inv());
FP();
ASSERT(inv());
}
} // End namespace deluxe
} // End namespace rosa
diff --git a/lib/deluxe/DeluxeExecutionPolicy.cpp b/lib/deluxe/DeluxeExecutionPolicy.cpp
index ee59bcd..bbea1ea 100644
--- a/lib/deluxe/DeluxeExecutionPolicy.cpp
+++ b/lib/deluxe/DeluxeExecutionPolicy.cpp
@@ -1,53 +1,67 @@
//===-- deluxe/DeluxeExecutionPolicy.cpp ------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file deluxe/DeluxeExecutionPolicy.cpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Implementation for rosa/deluxe/DeluxeExecutionPolicy.h.
///
//===----------------------------------------------------------------------===//
#include "rosa/deluxe/DeluxeExecutionPolicy.h"
#include "rosa/deluxe/DeluxeSystem.hpp"
#include "executionpolicies/Decimation.h"
#include "executionpolicies/AwaitAll.h"
#include "executionpolicies/AwaitAny.h"
namespace rosa {
namespace deluxe {
std::unique_ptr<DeluxeExecutionPolicy>
DeluxeExecutionPolicy::decimation(const size_t D) {
return std::unique_ptr<DeluxeExecutionPolicy>(new Decimation(D));
}
std::unique_ptr<DeluxeExecutionPolicy>
DeluxeExecutionPolicy::awaitAll(const std::set<size_t> &S) {
return std::unique_ptr<DeluxeExecutionPolicy>(new AwaitAll(S));
}
std::unique_ptr<DeluxeExecutionPolicy>
DeluxeExecutionPolicy::awaitAny(const std::set<size_t> &S) {
return std::unique_ptr<DeluxeExecutionPolicy>(new AwaitAny(S));
}
bool DeluxeExecutionPolicy::isDeluxeAgent(const AgentHandle H, const DeluxeSystem &S) const noexcept {
return S.isDeluxeAgent(H);
}
size_t DeluxeExecutionPolicy::numberOfDeluxeAgentInputs(
const AgentHandle H, const DeluxeSystem &S) const noexcept {
auto A = S.getDeluxeAgent(H);
return A ? A->NumberOfInputs : 0;
}
} // End namespace deluxe
} // End namespace rosa
+
+namespace std {
+
+string to_string(const rosa::deluxe::DeluxeExecutionPolicy &EP) {
+ return EP.dump();
+}
+
+ostream &operator<<(ostream &OS,
+ const rosa::deluxe::DeluxeExecutionPolicy &EP) {
+ OS << to_string(EP);
+ return OS;
+}
+
+} // End namespace std
diff --git a/lib/deluxe/DeluxeSensor.cpp b/lib/deluxe/DeluxeSensor.cpp
index 0175cd5..c5269f7 100755
--- a/lib/deluxe/DeluxeSensor.cpp
+++ b/lib/deluxe/DeluxeSensor.cpp
@@ -1,108 +1,113 @@
//===-- deluxe/DeluxeSensor.cpp ---------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file deluxe/DeluxeSensor.cpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief Implementation of rosa/deluxe/DeluxeSensor.hpp.
///
//===----------------------------------------------------------------------===//
#include "rosa/deluxe/DeluxeSensor.hpp"
#include "rosa/deluxe/DeluxeSystem.hpp"
namespace rosa {
namespace deluxe {
bool DeluxeSensor::inv(void) const noexcept {
// Check execution policy.
// \note The \c rosa::System the \c rosa::Unit is created with is a
// \c rosa::DeluxeSystem.
const DeluxeSystem &DS = static_cast<DeluxeSystem &>(Unit::system());
if (!ExecutionPolicy || !ExecutionPolicy->canHandle(Self, DS)) {
return false;
}
// All checks were successful, the invariant is held.
return true;
}
DeluxeSensor::~DeluxeSensor(void) noexcept {
ASSERT(inv());
LOG_TRACE("Destroying DeluxeSensor...");
// Make sure \p this object is not a registered *slave*.
if (Master) {
ASSERT(unwrapAgent(*Master).Kind == atoms::AgentKind); // Sanity check.
DeluxeAgent &M = static_cast<DeluxeAgent&>(unwrapAgent(*Master));
ASSERT(M.positionOfSlave(self()) != M.NumberOfInputs); // Sanity check.
M.registerSlave(M.positionOfSlave(self()), {});
Master = {};
}
}
const DeluxeExecutionPolicy &DeluxeSensor::executionPolicy(void) const
noexcept {
ASSERT(inv());
return *ExecutionPolicy;
}
bool DeluxeSensor::setExecutionPolicy(
std::unique_ptr<DeluxeExecutionPolicy> &&EP) noexcept {
ASSERT(inv());
+ LOG_TRACE_STREAM << "DeluxeSensor " << FullName
+ << " setting execution policy " << *EP << std::endl;
bool Success = false;
// \note The \c rosa::System the \c rosa::Unit is created with is a
// \c rosa::DeluxeSystem.
const DeluxeSystem &DS = static_cast<DeluxeSystem &>(Unit::system());
if (EP && EP->canHandle(self(), DS)) {
ExecutionPolicy.swap(EP);
Success = true;
+ } else {
+ LOG_TRACE_STREAM << "Execution policy " << *EP
+ << " cannot handle DeluxeSensor " << FullName << std::endl;
}
ASSERT(inv());
return Success;
}
Optional<AgentHandle> DeluxeSensor::master(void) const noexcept {
ASSERT(inv());
return Master;
}
void DeluxeSensor::registerMaster(const Optional<AgentHandle> _Master) noexcept {
ASSERT(inv() && (!_Master || unwrapAgent(*_Master).Kind == atoms::AgentKind));
Master = _Master;
ASSERT(inv());
}
void DeluxeSensor::clearSimulationDataSource(void) noexcept {
ASSERT(inv());
SFP = nullptr;
ASSERT(inv());
}
bool DeluxeSensor::simulationDataSourceIsSet(void) const noexcept {
ASSERT(inv());
return SFP != nullptr;
}
void DeluxeSensor::handleTrigger(atoms::Trigger) noexcept {
ASSERT(inv());
// Use \c rosa::deluxe::DeluxeSensor::SFP if set, otherwise
// \c rosa::deluxe::DeluxeSensor::FP.
const H &F = SFP ? SFP : FP;
F();
ASSERT(inv());
}
} // End namespace deluxe
} // End namespace rosa

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jul 3, 3:55 PM (10 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157284
Default Alt Text
(27 KB)

Event Timeline