XBT_PUBLIC void sg_link_data_set(sg_link_t link, void* data);
XBT_PUBLIC int sg_link_count();
XBT_PUBLIC sg_link_t* sg_link_list();
-XBT_PUBLIC void sg_link_exit();
SG_END_DECL()
#endif /* INCLUDE_SIMGRID_LINK_H_ */
protected:
friend s4u::Host;
+ friend s4u::Link;
friend s4u::Storage;
friend kernel::routing::NetPoint;
friend kernel::routing::NetZoneImpl;
+ friend kernel::resource::LinkImpl;
void host_register(std::string name, simgrid::s4u::Host* host);
void host_unregister(std::string name);
+ void link_register(std::string name, simgrid::s4u::Link* link);
+ void link_unregister(std::string name);
void storage_register(std::string name, simgrid::s4u::Storage* storage);
void storage_unregister(std::string name);
void netpoint_register(simgrid::kernel::routing::NetPoint* card);
size_t get_link_count();
std::vector<Link*> get_all_links();
std::vector<Link*> get_filtered_links(std::function<bool(Link*)> filter);
+ simgrid::s4u::Link* link_by_name(std::string name);
+ simgrid::s4u::Link* link_by_name_or_null(std::string name);
size_t get_actor_count();
std::vector<ActorPtr> get_all_actors();
// The private implementation, that never changes
kernel::resource::LinkImpl* const pimpl_;
+private:
+ bool currentlyDestroying_ = false;
+
public:
enum class SharingPolicy { SPLITDUPLEX = 2, SHARED = 1, FATPIPE = 0 };
+ virtual void destroy();
+ kernel::resource::LinkImpl* get_impl() { return pimpl_; }
+
/** @brief Retrieve a link from its name */
- static Link* by_name(const char* name);
+ static Link* by_name(std::string name);
+ static Link* by_name_or_null(std::string name);
/** @brief Retrieves the name of that link as a C++ string */
const std::string& get_name() const;
#include "simgrid/kernel/routing/NetPoint.hpp"
#include "simgrid/kernel/routing/NetZoneImpl.hpp"
#include "simgrid/s4u/Host.hpp"
+#include "simgrid/s4u/Link.hpp"
#include "src/surf/StorageImpl.hpp"
#include <algorithm>
for (auto const& kv : storages_)
if (kv.second)
kv.second->getImpl()->destroy();
+ for (auto const& kv : links_)
+ if (kv.second)
+ (kv.second)->destroy();
}
}
}
private:
std::map<std::string, simgrid::s4u::Host*> hosts_;
+ std::map<std::string, simgrid::s4u::Link*> links_;
std::map<std::string, simgrid::s4u::Storage*> storages_;
std::unordered_map<std::string, simgrid::kernel::routing::NetPoint*> netpoints_;
friend simgrid::s4u::Engine;
link.policy = cluster->sharing_policy;
sg_platf_new_link(&link);
- resource::LinkImpl* linkUp;
- resource::LinkImpl* linkDown;
+ s4u::Link* linkUp;
+ s4u::Link* linkDown;
if (link.policy == simgrid::s4u::Link::SharingPolicy::SPLITDUPLEX) {
- linkUp = resource::LinkImpl::by_name(link_id + "_UP");
- linkDown = resource::LinkImpl::by_name(link_id + "_DOWN");
+ linkUp = s4u::Link::by_name(link_id + "_UP");
+ linkDown = s4u::Link::by_name(link_id + "_DOWN");
} else {
- linkUp = resource::LinkImpl::by_name(link_id);
+ linkUp = s4u::Link::by_name(link_id);
linkDown = linkUp;
}
- private_links_.insert({position, {linkUp, linkDown}});
+ private_links_.insert({position, {linkUp->get_impl(), linkDown->get_impl()}});
}
}
}
XBT_DEBUG("Generating link %s", id.c_str());
resource::LinkImpl* link;
if (this->sharing_policy_ == s4u::Link::SharingPolicy::SPLITDUPLEX) {
- *linkup = resource::LinkImpl::by_name(linkTemplate.id + "_UP"); // check link?
- *linkdown = resource::LinkImpl::by_name(linkTemplate.id + "_DOWN"); // check link ?
+ *linkup = s4u::Link::by_name(linkTemplate.id + "_UP")->get_impl(); // check link?
+ *linkdown = s4u::Link::by_name(linkTemplate.id + "_DOWN")->get_impl(); // check link ?
} else {
- link = resource::LinkImpl::by_name(linkTemplate.id);
+ link = s4u::Link::by_name(linkTemplate.id)->get_impl();
*linkup = link;
*linkdown = link;
}
linkTemplate.policy = s4u::Link::SharingPolicy::SHARED;
linkTemplate.id = "limiter_"+std::to_string(id);
sg_platf_new_link(&linkTemplate);
- this->limiter_link_ = resource::LinkImpl::by_name(linkTemplate.id);
+ this->limiter_link_ = s4u::Link::by_name(linkTemplate.id)->get_impl();
}
if (cluster->loopback_bw || cluster->loopback_lat) {
linkTemplate.bandwidth = cluster->loopback_bw;
linkTemplate.policy = s4u::Link::SharingPolicy::FATPIPE;
linkTemplate.id = "loopback_"+ std::to_string(id);
sg_platf_new_link(&linkTemplate);
- this->loopback = resource::LinkImpl::by_name(linkTemplate.id);
+ this->loopback = s4u::Link::by_name(linkTemplate.id)->get_impl();
}
}
sg_platf_new_link(&linkTemplate);
if (cluster->sharing_policy == s4u::Link::SharingPolicy::SPLITDUPLEX) {
- std::string tmpID = std::string(linkTemplate.id) + "_UP";
- this->up_link_ = resource::LinkImpl::by_name(tmpID); // check link?
- tmpID = std::string(linkTemplate.id) + "_DOWN";
- this->down_link_ = resource::LinkImpl::by_name(tmpID); // check link ?
+ this->up_link_ = s4u::Link::by_name(linkTemplate.id + "_UP")->get_impl(); // check link?
+ this->down_link_ = s4u::Link::by_name(linkTemplate.id + "_DOWN")->get_impl(); // check link ?
} else {
- this->up_link_ = resource::LinkImpl::by_name(linkTemplate.id);
+ this->up_link_ = s4u::Link::by_name(linkTemplate.id)->get_impl();
this->down_link_ = this->up_link_;
}
uniqueId++;
resource::LinkImpl* linkUp;
resource::LinkImpl* linkDown;
if (link.policy == s4u::Link::SharingPolicy::SPLITDUPLEX) {
- std::string tmp_link = link_id + "_UP";
- linkUp = resource::LinkImpl::by_name(tmp_link);
- tmp_link = link_id + "_DOWN";
- linkDown = resource::LinkImpl::by_name(tmp_link);
+ linkUp = s4u::Link::by_name(link_id + "_UP")->get_impl();
+ linkDown = s4u::Link::by_name(link_id + "_DOWN")->get_impl();
} else {
- linkUp = resource::LinkImpl::by_name(link_id);
+ linkUp = s4u::Link::by_name(link_id)->get_impl();
linkDown = linkUp;
}
/*
return host == pimpl->hosts_.end() ? nullptr : host->second;
}
+simgrid::s4u::Link* Engine::link_by_name(std::string name)
+{
+ return pimpl->links_.at(name); // Will raise a std::out_of_range if the host does not exist
+}
+
+simgrid::s4u::Link* Engine::link_by_name_or_null(std::string name)
+{
+ auto link = pimpl->links_.find(name);
+ return link == pimpl->links_.end() ? nullptr : link->second;
+}
+
+void Engine::link_register(std::string name, simgrid::s4u::Link* link)
+{
+ pimpl->links_[name] = link;
+}
+
+void Engine::link_unregister(std::string name)
+{
+ pimpl->links_.erase(name);
+}
+
/** @brief Returns the amount of storages in the platform */
size_t Engine::get_storage_count()
{
/** @brief Returns the amount of links in the platform */
size_t Engine::get_link_count()
{
- return kernel::resource::LinkImpl::linksCount();
+ return pimpl->links_.size();
}
/** @brief Returns the list of all links found in the platform */
std::vector<Link*> Engine::get_all_links()
{
std::vector<Link*> res;
- kernel::resource::LinkImpl::linksList(&res);
+ for (auto const& kv : pimpl->links_)
+ res.push_back(kv.second);
return res;
}
std::vector<Link*> Engine::get_filtered_links(std::function<bool(Link*)> filter)
{
- // FIXME: This is a terrible implementation and should be done
- // without getting all links first.
- std::vector<Link*> res;
- kernel::resource::LinkImpl::linksList(&res);
std::vector<Link*> filtered_list;
- for (auto& link : res) {
- if (filter(link))
- filtered_list.push_back(link);
- }
+ for (auto const& kv : pimpl->links_)
+ if (filter(kv.second))
+ filtered_list.push_back(kv.second);
return filtered_list;
}
#include <algorithm>
+#include "simgrid/s4u/Engine.hpp"
#include "simgrid/s4u/Link.hpp"
#include "simgrid/sg_config.hpp"
#include "simgrid/simix.hpp"
simgrid::xbt::signal<void(kernel::resource::NetworkAction*, Host* src, Host* dst)> Link::on_communicate;
simgrid::xbt::signal<void(kernel::resource::NetworkAction*)> Link::on_communication_state_change;
-Link* Link::by_name(const char* name)
+void Link::destroy()
{
- kernel::resource::LinkImpl* res = kernel::resource::LinkImpl::by_name(name);
- if (res == nullptr)
- return nullptr;
- return &res->piface_;
+ if (not currentlyDestroying_) {
+ currentlyDestroying_ = true;
+ on_destruction(*this);
+ Engine::get_instance()->link_unregister(std::string(pimpl_->get_cname()));
+ }
}
+
+Link* Link::by_name(std::string name)
+{
+ return Engine::get_instance()->link_by_name(name);
+}
+
+Link* Link::by_name_or_null(std::string name)
+{
+ return Engine::get_instance()->link_by_name_or_null(name);
+}
+
const std::string& Link::get_name() const
{
return this->pimpl_->get_name();
}
int sg_link_count()
{
- return simgrid::kernel::resource::LinkImpl::linksCount();
+ return simgrid::s4u::Engine::get_instance()->get_link_count();
}
+
sg_link_t* sg_link_list()
{
- simgrid::kernel::resource::LinkImpl** list = simgrid::kernel::resource::LinkImpl::linksList();
- sg_link_t* res = (sg_link_t*)list; // Use the same memory area
+ std::vector<simgrid::s4u::Link*> links = simgrid::s4u::Engine::get_instance()->get_all_links();
- int size = sg_link_count();
- for (int i = 0; i < size; i++)
- res[i] = &(list[i]->piface_); // Convert each entry into its interface
+ sg_link_t* res = (sg_link_t*)malloc(sizeof(sg_link_t) * links.size());
+ memcpy(res, links.data(), sizeof(sg_link_t) * links.size());
return res;
}
-void sg_link_exit()
-{
- simgrid::kernel::resource::LinkImpl::linksExit();
-}
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "network_interface.hpp"
+#include "simgrid/s4u/Engine.hpp"
#include "simgrid/sg_config.hpp"
#include "src/surf/surf_interface.hpp"
#include "surf/surf.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network, surf, "Logging specific to the SURF network module");
-namespace simgrid {
-namespace kernel {
-namespace resource {
-
-/* List of links */
-std::unordered_map<std::string, LinkImpl*>* LinkImpl::links = new std::unordered_map<std::string, LinkImpl*>();
-
-LinkImpl* LinkImpl::by_name(std::string name)
-{
- auto link = links->find(name);
- return link == links->end() ? nullptr : link->second;
-}
-/** @brief Returns the amount of links in the platform */
-int LinkImpl::linksCount()
-{
- return links->size();
-}
-void LinkImpl::linksList(std::vector<s4u::Link*>* linkList)
-{
- for (auto const& kv : *links) {
- linkList->push_back(&kv.second->piface_);
- }
-}
-
-/** @brief Returns a list of all existing links */
-LinkImpl** LinkImpl::linksList()
-{
- LinkImpl** res = xbt_new(LinkImpl*, (int)links->size());
- int i = 0;
- for (auto const& kv : *links) {
- res[i] = kv.second;
- i++;
- }
- return res;
-}
-/** @brief destructor of the static data */
-void LinkImpl::linksExit()
-{
- for (auto const& kv : *links)
- (kv.second)->destroy();
- delete links;
-}
-}
-}
-} // namespace simgrid
-
/*********
* Model *
*********/
{
if (name != "__loopback__")
- xbt_assert(not LinkImpl::by_name(name), "Link '%s' declared several times in the platform.", name.c_str());
+ xbt_assert(not s4u::Link::by_name_or_null(name), "Link '%s' declared several times in the platform.", name.c_str());
latency_.scale = 1;
bandwidth_.scale = 1;
- links->insert({name, this});
+ s4u::Engine::get_instance()->link_register(name, &piface_);
XBT_DEBUG("Create link '%s'", name.c_str());
}
void set_data(void* d) { userdata_ = d; }
private:
void* userdata_ = nullptr;
-
- /* List of all links. FIXME: should move to the Engine */
- static std::unordered_map<std::string, LinkImpl*>* links;
-
-public:
- static LinkImpl* by_name(std::string name);
- static int linksCount();
- static LinkImpl** linksList();
- static void linksList(std::vector<s4u::Link*>* linkList);
- static void linksExit();
};
/**********
// other columns are to store one or more link for the node
//add a loopback link
- simgrid::kernel::resource::LinkImpl* linkUp = nullptr;
- simgrid::kernel::resource::LinkImpl* linkDown = nullptr;
+ simgrid::s4u::Link* linkUp = nullptr;
+ simgrid::s4u::Link* linkDown = nullptr;
if(cluster->loopback_bw > 0 || cluster->loopback_lat > 0){
std::string tmp_link = link_id + "_loopback";
XBT_DEBUG("<loopback\tid=\"%s\"\tbw=\"%f\"/>", tmp_link.c_str(), cluster->loopback_bw);
link.latency = cluster->loopback_lat;
link.policy = simgrid::s4u::Link::SharingPolicy::FATPIPE;
sg_platf_new_link(&link);
- linkUp = simgrid::kernel::resource::LinkImpl::by_name(tmp_link);
- linkDown = simgrid::kernel::resource::LinkImpl::by_name(tmp_link);
+ linkUp = simgrid::s4u::Link::by_name_or_null(tmp_link);
+ linkDown = simgrid::s4u::Link::by_name_or_null(tmp_link);
auto* as_cluster = static_cast<ClusterZone*>(current_as);
- as_cluster->private_links_.insert({as_cluster->node_pos(rankId), {linkUp, linkDown}});
+ as_cluster->private_links_.insert({as_cluster->node_pos(rankId), {linkUp->get_impl(), linkDown->get_impl()}});
}
//add a limiter link (shared link to account for maximal bandwidth of the node)
link.latency = 0;
link.policy = simgrid::s4u::Link::SharingPolicy::SHARED;
sg_platf_new_link(&link);
- linkDown = simgrid::kernel::resource::LinkImpl::by_name(tmp_link);
+ linkDown = simgrid::s4u::Link::by_name_or_null(tmp_link);
linkUp = linkDown;
- current_as->private_links_.insert({current_as->node_pos_with_loopback(rankId), {linkUp, linkDown}});
+ current_as->private_links_.insert(
+ {current_as->node_pos_with_loopback(rankId), {linkUp->get_impl(), linkDown->get_impl()}});
}
//call the cluster function that adds the others links
XBT_DEBUG("<link\tid=\"%s\" bw=\"%f\" lat=\"%f\"/>", link.id.c_str(), cluster->bb_bw, cluster->bb_lat);
sg_platf_new_link(&link);
- routing_cluster_add_backbone(simgrid::kernel::resource::LinkImpl::by_name(link.id));
+ routing_cluster_add_backbone(simgrid::s4u::Link::by_name(link.id)->get_impl());
}
XBT_DEBUG("</AS>");
xbt_assert(dynamic_cast<simgrid::kernel::routing::ClusterZone*>(current_routing),
"Only hosts from Cluster and Vivaldi ASes can get an host_link.");
- simgrid::kernel::resource::LinkImpl* linkUp = simgrid::kernel::resource::LinkImpl::by_name(hostlink->link_up);
- simgrid::kernel::resource::LinkImpl* linkDown = simgrid::kernel::resource::LinkImpl::by_name(hostlink->link_down);
+ simgrid::s4u::Link* linkUp = simgrid::s4u::Link::by_name_or_null(hostlink->link_up);
+ simgrid::s4u::Link* linkDown = simgrid::s4u::Link::by_name_or_null(hostlink->link_down);
xbt_assert(linkUp, "Link '%s' not found!", hostlink->link_up.c_str());
xbt_assert(linkDown, "Link '%s' not found!", hostlink->link_down.c_str());
surf_parse_error(std::string("Host_link for '") + hostlink->id.c_str() + "' is already defined!");
XBT_DEBUG("Push Host_link for host '%s' to position %u", netpoint->get_cname(), netpoint->id());
- as_cluster->private_links_.insert({netpoint->id(), {linkUp, linkDown}});
+ as_cluster->private_links_.insert({netpoint->id(), {linkUp->get_impl(), linkDown->get_impl()}});
}
void sg_platf_new_trace(simgrid::kernel::routing::TraceCreationArgs* trace)
void surf_exit()
{
simgrid::s4u::Engine::shutdown();
- sg_link_exit();
for (auto const& e : storage_types) {
simgrid::surf::StorageType* stype = e.second;
delete stype->properties;
switch (A_surfxml_link___ctn_direction) {
case AU_surfxml_link___ctn_direction:
case A_surfxml_link___ctn_direction_NONE:
- link = simgrid::kernel::resource::LinkImpl::by_name(A_surfxml_link___ctn_id);
+ link = simgrid::s4u::Link::by_name(std::string(A_surfxml_link___ctn_id))->get_impl();
break;
case A_surfxml_link___ctn_direction_UP:
- link = simgrid::kernel::resource::LinkImpl::by_name(std::string(A_surfxml_link___ctn_id) + "_UP");
+ link = simgrid::s4u::Link::by_name(std::string(A_surfxml_link___ctn_id) + "_UP")->get_impl();
break;
case A_surfxml_link___ctn_direction_DOWN:
- link = simgrid::kernel::resource::LinkImpl::by_name(std::string(A_surfxml_link___ctn_id) + "_DOWN");
+ link = simgrid::s4u::Link::by_name(std::string(A_surfxml_link___ctn_id) + "_DOWN")->get_impl();
break;
default:
surf_parse_error(std::string("Invalid direction for link ") + A_surfxml_link___ctn_id);
link.policy = simgrid::s4u::Link::SharingPolicy::SHARED;
sg_platf_new_link(&link);
- routing_cluster_add_backbone(simgrid::kernel::resource::LinkImpl::by_name(A_surfxml_backbone_id));
+ routing_cluster_add_backbone(simgrid::s4u::Link::by_name(std::string(A_surfxml_backbone_id))->get_impl());
}
void STag_surfxml_route(){