Logo AND Algorithmique Numérique Distribuée

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