Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of https://framagit.org/simgrid/simgrid
[simgrid.git] / src / kernel / resource / WifiLinkImpl.cpp
1 /* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include <simgrid/s4u/Host.hpp>
7
8 #include "src/kernel/activity/CommImpl.hpp"
9 #include "src/kernel/resource/WifiLinkImpl.hpp"
10
11 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_network);
12
13 namespace simgrid::kernel::resource {
14
15 /************
16  * Resource *
17  ************/
18
19 WifiLinkImpl::WifiLinkImpl(const std::string& name, const std::vector<double>& bandwidths, lmm::System* system)
20     : StandardLinkImpl(name)
21 {
22   this->set_constraint(system->constraint_new(this, 1));
23   for (auto bandwidth : bandwidths)
24     bandwidths_.push_back({bandwidth, 1.0, nullptr});
25   kernel::activity::CommImpl::on_start.connect(&update_bw_comm_start);
26   s4u::Link::on_communication_state_change_cb(&update_bw_comm_end);
27 }
28
29 void WifiLinkImpl::set_host_rate(const s4u::Host* host, int rate_level)
30 {
31   host_rates_[host->get_name()] = rate_level;
32 }
33
34 double WifiLinkImpl::get_host_rate(const s4u::Host* host) const
35 {
36   auto host_rates_it = host_rates_.find(host->get_name());
37
38   if (host_rates_it == host_rates_.end())
39     return -1;
40
41   int rate_id = host_rates_it->second;
42   xbt_assert(rate_id >= 0,
43              "Negative host wifi rate levels are invalid but host '%s' uses %d as a rate level on link '%s'",
44              host->get_cname(), rate_id, this->get_cname());
45   xbt_assert(rate_id < (int)bandwidths_.size(),
46              "Link '%s' only has %zu wifi rate levels, so the provided level %d is invalid for host '%s'.",
47              this->get_cname(), bandwidths_.size(), rate_id, host->get_cname());
48
49   Metric rate = bandwidths_[rate_id];
50   return rate.peak * rate.scale;
51 }
52
53 s4u::Link::SharingPolicy WifiLinkImpl::get_sharing_policy() const
54 {
55   return s4u::Link::SharingPolicy::WIFI;
56 }
57
58 size_t WifiLinkImpl::get_host_count() const
59 {
60   return host_rates_.size();
61 }
62
63 double WifiLinkImpl::wifi_link_dynamic_sharing(const WifiLinkImpl& link, double /*capacity*/, int /*n*/)
64 {
65   double ratio = link.get_max_ratio();
66   XBT_DEBUG("New ratio value concurrency %d: %lf of link capacity on link %s", link.nb_active_flux_, ratio, link.get_name().c_str());
67   return ratio;
68 }
69
70 void WifiLinkImpl::inc_active_flux()
71 {
72   xbt_assert(nb_active_flux_ >= 0, "Negative nb_active_flux should not exist");
73   nb_active_flux_++;
74 }
75
76 void WifiLinkImpl::dec_active_flux()
77 {
78   xbt_assert(nb_active_flux_ > 0, "Negative nb_active_flux should not exist");
79   nb_active_flux_--;
80 }
81
82 void WifiLinkImpl::update_bw_comm_start(const kernel::activity::CommImpl& comm)
83 {
84   auto const* actionWifi = dynamic_cast<const simgrid::kernel::resource::WifiLinkAction*>(comm.model_action_);
85   if (actionWifi == nullptr)
86     return;
87
88   if (auto* link_src = actionWifi->get_src_link()) {
89     link_src->inc_active_flux();
90   }
91   if (auto* link_dst = actionWifi->get_dst_link()) {
92     link_dst->inc_active_flux();
93   }
94 }
95
96 void WifiLinkImpl::update_bw_comm_end(const simgrid::kernel::resource::NetworkAction& action,
97                                       simgrid::kernel::resource::Action::State /*state*/)
98 {
99   if (action.get_state() != kernel::resource::Action::State::FINISHED)
100     return;
101
102   auto const* actionWifi = dynamic_cast<const simgrid::kernel::resource::WifiLinkAction*>(&action);
103   if (actionWifi == nullptr)
104     return;
105
106   if (auto* link_src = actionWifi->get_src_link()) {
107     link_src->dec_active_flux();
108   }
109   if (auto* link_dst = actionWifi->get_dst_link()) {
110     link_dst->dec_active_flux();
111   }
112 }
113
114 double WifiLinkImpl::get_max_ratio() const
115 {
116   double new_peak;
117   if (nb_active_flux_ > conc_lim_) {
118     new_peak = (nb_active_flux_-conc_lim_) * co_acc_ + x0_;
119     XBT_DEBUG("Wi-Fi link peak=(%d-%d)*%lf+%lf=%lf", nb_active_flux_, conc_lim_, co_acc_, x0_, new_peak);
120   } else {
121     new_peak = x0_;
122     XBT_DEBUG("Wi-Fi link peak=%lf", x0_);
123   }
124   // should be the new maximum bandwidth ratio (comparison between max throughput without concurrency and with it)
125   double propCap = new_peak / x0_;
126
127   return propCap;
128 }
129
130 bool WifiLinkImpl::toggle_callback()
131 {
132   if (not use_callback_) {
133       XBT_DEBUG("Activate throughput reduction mechanism");
134     use_callback_ = true;
135     this->set_sharing_policy(
136         simgrid::s4u::Link::SharingPolicy::WIFI,
137         std::bind(&wifi_link_dynamic_sharing, std::cref(*this), std::placeholders::_1, std::placeholders::_2));
138   }
139   return use_callback_;
140 }
141
142 void WifiLinkImpl::set_latency(double value)
143 {
144   xbt_assert(value == 0, "Latency cannot be set for WiFi Links.");
145 }
146 } // namespace simgrid::kernel::resource