Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
have the maxmin system create by itself what it needs for selective update
[simgrid.git] / src / kernel / resource / Action.cpp
1 /* Copyright (c) 2004-2018. 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/kernel/resource/Action.hpp"
7 #include "simgrid/kernel/resource/Model.hpp"
8 #include "src/kernel/lmm/maxmin.hpp"
9 #include "src/surf/surf_interface.hpp"
10
11 XBT_LOG_NEW_CATEGORY(kernel, "Logging specific to the internals of SimGrid");
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(resource, kernel, "Logging specific to the resources");
13
14 namespace simgrid {
15 namespace kernel {
16 namespace resource {
17
18 Action::Action(simgrid::kernel::resource::Model* model, double cost, bool failed) : Action(model, cost, failed, nullptr)
19 {
20 }
21
22 Action::Action(simgrid::kernel::resource::Model* model, double cost, bool failed, kernel::lmm::Variable* var)
23     : remains_(cost), start_time_(surf_get_clock()), cost_(cost), model_(model), variable_(var)
24 {
25   if (failed)
26     state_set_ = get_model()->get_failed_action_set();
27   else
28     state_set_ = get_model()->get_running_action_set();
29
30   state_set_->push_back(*this);
31 }
32
33 Action::~Action()
34 {
35   if (state_set_hook_.is_linked())
36     simgrid::xbt::intrusive_erase(*state_set_, *this);
37   if (get_variable())
38     get_model()->get_maxmin_system()->variable_free(get_variable());
39
40   /* remove from heap on need (ie, if selective update) */
41   heapRemove();
42   if (modified_set_hook_.is_linked())
43     simgrid::xbt::intrusive_erase(*get_model()->get_modified_set(), *this);
44
45   xbt_free(category_);
46 }
47
48 void Action::finish(Action::State state)
49 {
50   finish_time_ = surf_get_clock();
51   set_state(state);
52   set_remains(0);
53 }
54
55 Action::State Action::get_state() const
56 {
57   if (state_set_ == model_->get_ready_action_set())
58     return Action::State::ready;
59   if (state_set_ == model_->get_running_action_set())
60     return Action::State::running;
61   if (state_set_ == model_->get_failed_action_set())
62     return Action::State::failed;
63   if (state_set_ == model_->get_done_action_set())
64     return Action::State::done;
65   return Action::State::not_in_the_system;
66 }
67
68 void Action::set_state(Action::State state)
69 {
70   simgrid::xbt::intrusive_erase(*state_set_, *this);
71   switch (state) {
72     case Action::State::ready:
73       state_set_ = model_->get_ready_action_set();
74       break;
75     case Action::State::running:
76       state_set_ = model_->get_running_action_set();
77       break;
78     case Action::State::failed:
79       state_set_ = model_->get_failed_action_set();
80       break;
81     case Action::State::done:
82       state_set_ = model_->get_done_action_set();
83       break;
84     default:
85       state_set_ = nullptr;
86       break;
87   }
88   if (state_set_)
89     state_set_->push_back(*this);
90 }
91
92 double Action::get_bound() const
93 {
94   return variable_ ? variable_->get_bound() : 0;
95 }
96
97 void Action::set_bound(double bound)
98 {
99   XBT_IN("(%p,%g)", this, bound);
100   if (variable_)
101     get_model()->get_maxmin_system()->update_variable_bound(variable_, bound);
102
103   if (get_model()->getUpdateMechanism() == Model::UpdateAlgo::Lazy && get_last_update() != surf_get_clock())
104     heapRemove();
105   XBT_OUT();
106 }
107
108 void Action::set_category(const char* category)
109 {
110   category_ = xbt_strdup(category);
111 }
112
113 void Action::ref()
114 {
115   refcount_++;
116 }
117
118 void Action::set_max_duration(double duration)
119 {
120   max_duration_ = duration;
121   if (get_model()->getUpdateMechanism() == Model::UpdateAlgo::Lazy) // remove action from the heap
122     heapRemove();
123 }
124
125 void Action::set_priority(double weight)
126 {
127   XBT_IN("(%p,%g)", this, weight);
128   sharing_priority_ = weight;
129   get_model()->get_maxmin_system()->update_variable_weight(get_variable(), weight);
130
131   if (get_model()->getUpdateMechanism() == Model::UpdateAlgo::Lazy)
132     heapRemove();
133   XBT_OUT();
134 }
135
136 void Action::cancel()
137 {
138   set_state(Action::State::failed);
139   if (get_model()->getUpdateMechanism() == Model::UpdateAlgo::Lazy) {
140     if (modified_set_hook_.is_linked())
141       simgrid::xbt::intrusive_erase(*get_model()->get_modified_set(), *this);
142     heapRemove();
143   }
144 }
145
146 int Action::unref()
147 {
148   refcount_--;
149   if (not refcount_) {
150     delete this;
151     return 1;
152   }
153   return 0;
154 }
155
156 void Action::suspend()
157 {
158   XBT_IN("(%p)", this);
159   if (suspended_ != SuspendStates::sleeping) {
160     get_model()->get_maxmin_system()->update_variable_weight(get_variable(), 0.0);
161     if (get_model()->getUpdateMechanism() == Model::UpdateAlgo::Lazy) {
162       heapRemove();
163       if (state_set_ == get_model()->get_running_action_set() && sharing_priority_ > 0) {
164         // If we have a lazy model, we need to update the remaining value accordingly
165         update_remains_lazy(surf_get_clock());
166       }
167     }
168     suspended_ = SuspendStates::suspended;
169   }
170   XBT_OUT();
171 }
172
173 void Action::resume()
174 {
175   XBT_IN("(%p)", this);
176   if (suspended_ != SuspendStates::sleeping) {
177     get_model()->get_maxmin_system()->update_variable_weight(get_variable(), get_priority());
178     suspended_ = SuspendStates::not_suspended;
179     if (get_model()->getUpdateMechanism() == Model::UpdateAlgo::Lazy)
180       heapRemove();
181   }
182   XBT_OUT();
183 }
184
185 bool Action::is_suspended()
186 {
187   return suspended_ == SuspendStates::suspended;
188 }
189 /* insert action on heap using a given key and a hat (heap_action_type)
190  * a hat can be of three types for communications:
191  *
192  * NORMAL = this is a normal heap entry stating the date to finish transmitting
193  * LATENCY = this is a heap entry to warn us when the latency is payed
194  * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
195  */
196 void Action::heapInsert(double key, Action::Type hat)
197 {
198   type_       = hat;
199   heap_hook_  = get_model()->getActionHeap().emplace(std::make_pair(key, this));
200 }
201
202 void Action::heapRemove()
203 {
204   type_ = Action::Type::NOTSET;
205   if (heap_hook_) {
206     get_model()->getActionHeap().erase(*heap_hook_);
207     clearHeapHandle();
208   }
209 }
210
211 void Action::heapUpdate(double key, Action::Type hat)
212 {
213   type_ = hat;
214   if (heap_hook_) {
215     get_model()->getActionHeap().update(*heap_hook_, std::make_pair(key, this));
216   } else {
217     heap_hook_ = get_model()->getActionHeap().emplace(std::make_pair(key, this));
218   }
219 }
220
221 double Action::get_remains()
222 {
223   XBT_IN("(%p)", this);
224   /* update remains before return it */
225   if (get_model()->getUpdateMechanism() == Model::UpdateAlgo::Lazy) /* update remains before return it */
226     update_remains_lazy(surf_get_clock());
227   XBT_OUT();
228   return remains_;
229 }
230
231 void Action::update_max_duration(double delta)
232 {
233   double_update(&max_duration_, delta, sg_surf_precision);
234 }
235 void Action::update_remains(double delta)
236 {
237   double_update(&remains_, delta, sg_maxmin_precision * sg_surf_precision);
238 }
239
240 void Action::set_last_update()
241 {
242   last_update_ = surf_get_clock();
243 }
244
245 } // namespace surf
246 } // namespace simgrid
247 } // namespace simgrid