/**
* @file tests/multithreading/simple/graph_manager.cpp
* @author The ARTIS Development Team
* See the AUTHORS or Authors.txt file
*/
/*
* ARTIS - the multimodeling and simulation environment
* This file is a part of the ARTIS environment
*
* Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef TESTS_MULTITHREADING_SIMPLE_GRAPH_MANAGER_HPP
#define TESTS_MULTITHREADING_SIMPLE_GRAPH_MANAGER_HPP
#include
#include
#include
#include
namespace artis {
namespace tests {
namespace multithreading {
namespace simple {
class LinksGraphManager :
public artis::pdevs::GraphManager
{
public:
enum submodels
{
LINK_1, LINK_2
};
struct inputs
{
enum values
{
IN_1, IN_2
};
};
struct outputs
{
enum values
{
OUT_1, OUT_2
};
};
LinksGraphManager(
artis::common::Coordinator *coordinator,
const GeneratorParameters ¶meters,
const artis::common::NoParameters &graph_parameters)
:
artis::pdevs::GraphManager(
coordinator, parameters, graph_parameters),
_link_1("link_1", artis::common::NoParameters()),
_link_2("link_2", artis::common::NoParameters())
{
add_child(LINK_1, &_link_1);
add_child(LINK_2, &_link_2);
coordinator->input_ports({{inputs::IN_1, "in_1"},
{inputs::IN_2, "in_2"}});
coordinator->output_ports({{outputs::OUT_1, "out_1"},
{outputs::OUT_2, "out_2"}});
in({coordinator, inputs::IN_1})
>> out({&_link_1, Link::inputs::IN});
in({coordinator, inputs::IN_2})
>> out({&_link_2, Link::inputs::IN});
out({&_link_1, Link::outputs::OUT})
>> out({coordinator, outputs::OUT_1});
out({&_link_2, Link::outputs::OUT})
>> out({coordinator, outputs::OUT_2});
}
~LinksGraphManager() override = default;
common::DoubleTime::type
lookahead(const common::DoubleTime::type &t) const override
{
std::vector lookaheads = {_link_1.lookahead(t),
_link_2.lookahead(t)};
return *std::min(lookaheads.begin(), lookaheads.end());
}
void init()
{}
void start(common::DoubleTime::type /* t */)
{}
void transition(const common::Models & /* receivers */,
artis::common::DoubleTime::type /* t */)
{}
private:
artis::pdevs::Simulator _link_1;
artis::pdevs::Simulator _link_2;
};
class SimpleGraphManager :
public artis::pdevs::GraphManager
{
public:
enum submodels
{
GENERATOR, LINK_1_2, LINK_3_4, LINK_5_6, LINK_7_8, COUNTER
};
SimpleGraphManager(
artis::common::Coordinator *coordinator,
const GeneratorParameters ¶meters,
const artis::common::NoParameters &graph_parameters)
:
artis::pdevs::GraphManager(
coordinator, parameters, graph_parameters),
_generator("generator", parameters),
_link_1_2("link_1_2", parameters, artis::common::NoParameters()),
_link_3_4("link_3_4", parameters, artis::common::NoParameters()),
_link_5_6("link_5_6", parameters, artis::common::NoParameters()),
_link_7_8("link_7_8", parameters, artis::common::NoParameters()),
_counter("counter", artis::common::NoParameters())
{
add_child(GENERATOR, &_generator);
add_child(LINK_1_2, &_link_1_2);
add_child(LINK_3_4, &_link_3_4);
add_child(LINK_5_6, &_link_5_6);
add_child(LINK_7_8, &_link_7_8);
add_child(COUNTER, &_counter);
out({&_generator, Generator::outputs::OUT})
>> in({&_link_1_2, LinksGraphManager::inputs::IN_1});
out({&_generator, Generator::outputs::OUT + 1})
>> in({&_link_1_2, LinksGraphManager::inputs::IN_2});
out({&_generator, Generator::outputs::OUT + 2})
>> in({&_link_3_4, LinksGraphManager::inputs::IN_1});
out({&_generator, Generator::outputs::OUT + 3})
>> in({&_link_3_4, LinksGraphManager::inputs::IN_2});
out({&_generator, Generator::outputs::OUT + 4})
>> in({&_link_5_6, LinksGraphManager::inputs::IN_1});
out({&_generator, Generator::outputs::OUT + 5})
>> in({&_link_5_6, LinksGraphManager::inputs::IN_2});
out({&_generator, Generator::outputs::OUT + 6})
>> in({&_link_7_8, LinksGraphManager::inputs::IN_1});
out({&_generator, Generator::outputs::OUT + 7})
>> in({&_link_7_8, LinksGraphManager::inputs::IN_2});
out({&_link_1_2, LinksGraphManager::outputs::OUT_1})
>> in({&_counter, Counter::inputs::IN});
out({&_link_1_2, LinksGraphManager::outputs::OUT_2})
>> in({&_counter, Counter::inputs::IN});
out({&_link_3_4, LinksGraphManager::outputs::OUT_1})
>> in({&_counter, Counter::inputs::IN});
out({&_link_3_4, LinksGraphManager::outputs::OUT_2})
>> in({&_counter, Counter::inputs::IN});
out({&_link_5_6, LinksGraphManager::outputs::OUT_1})
>> in({&_counter, Counter::inputs::IN});
out({&_link_5_6, LinksGraphManager::outputs::OUT_2})
>> in({&_counter, Counter::inputs::IN});
out({&_link_7_8, LinksGraphManager::outputs::OUT_1})
>> in({&_counter, Counter::inputs::IN});
out({&_link_7_8, LinksGraphManager::outputs::OUT_2})
>> in({&_counter, Counter::inputs::IN});
}
~SimpleGraphManager() override = default;
common::DoubleTime::type
lookahead(const common::DoubleTime::type &t) const override
{
std::vector lookaheads = {_generator.lookahead(t),
_link_1_2.lookahead(t),
_link_3_4.lookahead(t),
_link_5_6.lookahead(t),
_link_7_8.lookahead(t),
_counter.lookahead(t)};
return *std::min(lookaheads.begin(), lookaheads.end());
}
void init()
{
_link_1_2.set_sender(
(dynamic_cast< artis::pdevs::multithreading::Coordinator<
artis::common::DoubleTime,
SimpleGraphManager,
GeneratorParameters,
artis::common::NoParameters> *>(this->coordinator()))->get_sender());
_link_3_4.set_sender(
(dynamic_cast< artis::pdevs::multithreading::Coordinator<
artis::common::DoubleTime,
SimpleGraphManager,
GeneratorParameters,
artis::common::NoParameters> *>(this->coordinator()))->get_sender());
_link_5_6.set_sender(
(dynamic_cast< artis::pdevs::multithreading::Coordinator<
artis::common::DoubleTime,
SimpleGraphManager,
GeneratorParameters,
artis::common::NoParameters> *>(this->coordinator()))->get_sender());
_link_7_8.set_sender(
(dynamic_cast< artis::pdevs::multithreading::Coordinator<
artis::common::DoubleTime,
SimpleGraphManager,
GeneratorParameters,
artis::common::NoParameters> *>(this->coordinator()))->get_sender());
}
void start(common::DoubleTime::type t)
{
_link_1_2.get_sender().send(
artis::pdevs::multithreading::start_message<
artis::common::DoubleTime>(t));
_link_3_4.get_sender().send(
artis::pdevs::multithreading::start_message<
artis::common::DoubleTime>(t));
_link_5_6.get_sender().send(
artis::pdevs::multithreading::start_message<
artis::common::DoubleTime>(t));
_link_7_8.get_sender().send(
artis::pdevs::multithreading::start_message<
artis::common::DoubleTime>(t));
}
void transition(const common::Models &receivers,
artis::common::DoubleTime::type t)
{
std::for_each(receivers.begin(), receivers.end(),
[this, t](const common::Model *model) {
if (not model->is_atomic()) {
if (model == &_link_1_2) {
_link_1_2.get_sender().send(
artis::pdevs::multithreading::transition_message<
artis::common::DoubleTime>(t));
} else if (model == &_link_3_4) {
_link_3_4.get_sender().send(
artis::pdevs::multithreading::transition_message<
artis::common::DoubleTime>(t));
} else if (model == &_link_5_6) {
_link_5_6.get_sender().send(
artis::pdevs::multithreading::transition_message<
artis::common::DoubleTime>(t));
} else if (model == &_link_7_8) {
_link_7_8.get_sender().send(
artis::pdevs::multithreading::transition_message<
artis::common::DoubleTime>(t));
}
}
});
}
private:
artis::pdevs::Simulator _generator;
/*
artis::pdevs::Coordinator _link_1_2;
artis::pdevs::Coordinator _link_3_4;
artis::pdevs::Coordinator _link_5_6;
artis::pdevs::Coordinator _link_7_8;
*/
artis::pdevs::multithreading::Coordinator _link_1_2;
artis::pdevs::multithreading::Coordinator _link_3_4;
artis::pdevs::multithreading::Coordinator _link_5_6;
artis::pdevs::multithreading::Coordinator _link_7_8;
artis::pdevs::Simulator _counter;
};
}
}
}
} // namespace artis tests multithreading simple
#endif