#include <simgrid/modelchecker.h>
#include <simgrid/s4u/Engine.hpp>
-#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v333)
-#include <simgrid/simix.h>
-
#include "mc/mc.h"
#include "src/instr/instr_private.hpp"
#include "src/kernel/EngineImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
+#include "src/kernel/resource/SplitDuplexLinkImpl.hpp"
+#include "src/kernel/resource/StandardLinkImpl.hpp"
#include "src/mc/mc_replay.hpp"
+#include "src/surf/HostImpl.hpp"
+#include "xbt/config.hpp"
#include <algorithm>
#include <string>
static simgrid::kernel::actor::ActorCode maestro_code;
-namespace simgrid {
-namespace s4u {
+namespace simgrid::s4u {
xbt::signal<void()> Engine::on_platform_creation;
xbt::signal<void()> Engine::on_platform_created;
xbt::signal<void()> Engine::on_simulation_start;
/** Returns the amount of hosts in the platform */
size_t Engine::get_host_count() const
{
- return pimpl->hosts_.size();
+ return get_all_hosts().size();
}
std::vector<Host*> Engine::get_all_hosts() const
{
- std::vector<Host*> res;
- for (auto const& kv : pimpl->hosts_)
- res.push_back(kv.second);
- return res;
+ return get_filtered_hosts([](const Host*) { return true; });
}
std::vector<Host*> Engine::get_filtered_hosts(const std::function<bool(Host*)>& filter) const
{
std::vector<Host*> hosts;
- for (auto const& kv : pimpl->hosts_) {
- if (filter(kv.second))
- hosts.push_back(kv.second);
+ if (pimpl->netzone_root_) {
+ hosts = pimpl->netzone_root_->get_filtered_hosts(filter);
}
+ /* Sort hosts in lexicographical order: keep same behavior when the hosts were saved on Engine
+ * Some tests do a get_all_hosts() and selects hosts in this order */
+ std::sort(hosts.begin(), hosts.end(), [](const auto* h1, const auto* h2) { return h1->get_name() < h2->get_name(); });
return hosts;
}
-void Engine::host_register(const std::string& name, Host* host)
-{
- pimpl->hosts_[name] = host;
-}
-
-void Engine::host_unregister(const std::string& name)
-{
- pimpl->hosts_.erase(name);
-}
-
/** @brief Find a host from its name.
*
* @throw std::invalid_argument if the searched host does not exist.
*/
Host* Engine::host_by_name(const std::string& name) const
{
- auto host = pimpl->hosts_.find(name);
- if (host == pimpl->hosts_.end())
+ auto* host = host_by_name_or_null(name);
+ if (not host)
throw std::invalid_argument(std::string("Host not found: '") + name + std::string("'"));
- return host->second;
+ return host;
}
/** @brief Find a host from its name (or nullptr if that host does not exist) */
Host* Engine::host_by_name_or_null(const std::string& name) const
{
- auto host = pimpl->hosts_.find(name);
- return host == pimpl->hosts_.end() ? nullptr : host->second;
+ Host* host = nullptr;
+ if (pimpl->netzone_root_) {
+ auto* host_impl = pimpl->netzone_root_->get_host_by_name_or_null(name);
+ if (host_impl)
+ host = host_impl->get_iface();
+ }
+ return host;
}
/** @brief Find a link from its name.
*/
Link* Engine::link_by_name(const std::string& name) const
{
- auto link = pimpl->links_.find(name);
- if (link == pimpl->links_.end())
+ auto* link = link_by_name_or_null(name);
+ if (not link)
throw std::invalid_argument(std::string("Link not found: ") + name);
- return link->second->get_iface();
+ return link;
}
SplitDuplexLink* Engine::split_duplex_link_by_name(const std::string& name) const
{
- auto link = pimpl->split_duplex_links_.find(name);
- if (link == pimpl->split_duplex_links_.end())
+ auto* link_impl = pimpl->netzone_root_ ? pimpl->netzone_root_->get_split_duplex_link_by_name_or_null(name) : nullptr;
+ if (not link_impl)
throw std::invalid_argument(std::string("Link not found: ") + name);
- return link->second->get_iface();
+ return link_impl->get_iface();
}
/** @brief Find a link from its name (or nullptr if that link does not exist) */
Link* Engine::link_by_name_or_null(const std::string& name) const
{
- auto link = pimpl->links_.find(name);
- return link == pimpl->links_.end() ? nullptr : link->second->get_iface();
+ Link* link = nullptr;
+ if (pimpl->netzone_root_) {
+ /* keep behavior where internal __loopback__ link from network model is given to user */
+ if (name == "__loopback__")
+ return pimpl->netzone_root_->get_network_model()->loopback_->get_iface();
+ auto* link_impl = pimpl->netzone_root_->get_link_by_name_or_null(name);
+ if (link_impl)
+ link = link_impl->get_iface();
+ }
+ return link;
}
-/** @brief Find a mailox from its name or create one if it does not exist) */
+/** @brief Find a mailbox from its name or create one if it does not exist) */
Mailbox* Engine::mailbox_by_name_or_create(const std::string& name) const
{
/* two actors may have pushed the same mbox_create simcall at the same time */
kernel::activity::MailboxImpl* mbox = kernel::actor::simcall_answered([&name, this] {
- auto m = pimpl->mailboxes_.emplace(name, nullptr);
- if (m.second) {
- m.first->second = new kernel::activity::MailboxImpl(name);
- XBT_DEBUG("Creating a mailbox at %p with name %s", m.first->second, name.c_str());
+ auto [m, inserted] = pimpl->mailboxes_.try_emplace(name, nullptr);
+ if (inserted) {
+ m->second = new kernel::activity::MailboxImpl(name);
+ XBT_DEBUG("Creating a mailbox at %p with name %s", m->second, name.c_str());
}
- return m.first->second;
+ return m->second;
});
return mbox->get_iface();
}
-void Engine::link_register(const std::string& name, const Link* link)
-{
- pimpl->links_[name] = link->get_impl();
-}
-
-void Engine::link_unregister(const std::string& name)
-{
- pimpl->links_.erase(name);
-}
-
/** @brief Returns the amount of links in the platform */
size_t Engine::get_link_count() const
{
- return pimpl->links_.size();
+ int count = 0;
+ if (pimpl->netzone_root_) {
+ count += pimpl->netzone_root_->get_link_count();
+ /* keep behavior where internal __loopback__ link from network model is given to user */
+ count += pimpl->netzone_root_->get_network_model()->loopback_ ? 1 : 0;
+ }
+ return count;
}
/** @brief Returns the list of all links found in the platform */
std::vector<Link*> Engine::get_all_links() const
{
- std::vector<Link*> res;
- for (auto const& kv : pimpl->links_)
- res.push_back(kv.second->get_iface());
- return res;
+ return get_filtered_links([](const Link*) { return true; });
}
std::vector<Link*> Engine::get_filtered_links(const std::function<bool(Link*)>& filter) const
{
- std::vector<Link*> filtered_list;
- for (auto const& kv : pimpl->links_) {
- Link* l = kv.second->get_iface();
- if (filter(l))
- filtered_list.push_back(l);
+ std::vector<Link*> res;
+ if (pimpl->netzone_root_) {
+ res = pimpl->netzone_root_->get_filtered_links(filter);
+ /* keep behavior where internal __loopback__ link from network model is given to user */
+ if (pimpl->netzone_root_->get_network_model()->loopback_ &&
+ filter(pimpl->netzone_root_->get_network_model()->loopback_->get_iface()))
+ res.push_back(pimpl->netzone_root_->get_network_model()->loopback_->get_iface());
}
- return filtered_list;
+ return res;
}
size_t Engine::get_actor_count() const
std::vector<ActorPtr> Engine::get_all_actors() const
{
std::vector<ActorPtr> actor_list;
- for (auto const& kv : pimpl->get_actor_list()) {
- actor_list.push_back(kv.second->get_iface());
+ for (auto const& [_, actor] : pimpl->get_actor_list()) {
+ actor_list.push_back(actor->get_iface());
}
return actor_list;
}
std::vector<ActorPtr> Engine::get_filtered_actors(const std::function<bool(ActorPtr)>& filter) const
{
std::vector<ActorPtr> actor_list;
- for (auto const& kv : pimpl->get_actor_list()) {
- if (filter(kv.second->get_iface()))
- actor_list.push_back(kv.second->get_iface());
+ for (auto const& [_, actor] : pimpl->get_actor_list()) {
+ if (filter(actor->get_iface()))
+ actor_list.push_back(actor->get_iface());
}
return actor_list;
}
}
void Engine::run_until(double max_date) const
{
- static bool callback_called = false;
- if (not callback_called) {
+ if (static bool callback_called = false; not callback_called) {
on_simulation_start();
callback_called = true;
}
std::vector<kernel::routing::NetPoint*> Engine::get_all_netpoints() const
{
std::vector<kernel::routing::NetPoint*> res;
- for (auto const& kv : pimpl->netpoints_)
- res.push_back(kv.second);
+ for (auto const& [_, netpoint] : pimpl->netpoints_)
+ res.push_back(netpoint);
return res;
}
config::set_value(name.c_str(), value);
}
-Engine* Engine::set_default_comm_data_copy_callback(void (*callback)(kernel::activity::CommImpl*, void*, size_t))
+Engine* Engine::set_default_comm_data_copy_callback(
+ const std::function<void(kernel::activity::CommImpl*, void*, size_t)>& callback)
{
kernel::activity::CommImpl::set_copy_data_callback(callback);
return this;
}
-} // namespace s4u
-} // namespace simgrid
-
-double SIMIX_get_clock() // XBT_ATTRIB_DEPRECATED_v332
-{
- return simgrid::s4u::Engine::get_clock();
-}
+} // namespace simgrid::s4u
/* **************************** Public C interface *************************** */
void simgrid_init(int* argc, char** argv)
#endif
maestro_code = std::bind(code, data);
}
-void SIMIX_set_maestro(void (*code)(void*), void* data) // XBT_ATTRIB_DEPRECATED_v333
-{
- simgrid_set_maestro(code, data);
-}