Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
start snake_casing resource::Model
[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   if (get_model()->getUpdateMechanism() == UM_LAZY) {
40     /* remove from heap */
41     heapRemove();
42     if (modified_set_hook_.is_linked())
43       simgrid::xbt::intrusive_erase(*get_model()->get_modified_set(), *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_->get_ready_action_set())
59     return Action::State::ready;
60   if (state_set_ == model_->get_running_action_set())
61     return Action::State::running;
62   if (state_set_ == model_->get_failed_action_set())
63     return Action::State::failed;
64   if (state_set_ == model_->get_done_action_set())
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_->get_ready_action_set();
75       break;
76     case Action::State::running:
77       state_set_ = model_->get_running_action_set();
78       break;
79     case Action::State::failed:
80       state_set_ = model_->get_failed_action_set();
81       break;
82     case Action::State::done:
83       state_set_ = model_->get_done_action_set();
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()->get_maxmin_system()->update_variable_bound(variable_, bound);
103
104   if (get_model()->getUpdateMechanism() == UM_LAZY && get_last_update() != surf_get_clock())
105     heapRemove();
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();
124 }
125
126 void Action::set_priority(double weight)
127 {
128   XBT_IN("(%p,%g)", this, weight);
129   sharing_priority_ = weight;
130   get_model()->get_maxmin_system()->update_variable_weight(get_variable(), weight);
131
132   if (get_model()->getUpdateMechanism() == UM_LAZY)
133     heapRemove();
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()->get_modified_set(), *this);
143     heapRemove();
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()->get_maxmin_system()->update_variable_weight(get_variable(), 0.0);
162     if (get_model()->getUpdateMechanism() == UM_LAZY) {
163       heapRemove();
164       if (state_set_ == get_model()->get_running_action_set() && sharing_priority_ > 0) {
165         // If we have a lazy model, we need to update the remaining value accordingly
166         update_remains_lazy(surf_get_clock());
167       }
168     }
169     suspended_ = SuspendStates::suspended;
170   }
171   XBT_OUT();
172 }
173
174 void Action::resume()
175 {
176   XBT_IN("(%p)", this);
177   if (suspended_ != SuspendStates::sleeping) {
178     get_model()->get_maxmin_system()->update_variable_weight(get_variable(), get_priority());
179     suspended_ = SuspendStates::not_suspended;
180     if (get_model()->getUpdateMechanism() == UM_LAZY)
181       heapRemove();
182   }
183   XBT_OUT();
184 }
185
186 bool Action::is_suspended()
187 {
188   return suspended_ == SuspendStates::suspended;
189 }
190 /* insert action on heap using a given key and a hat (heap_action_type)
191  * a hat can be of three types for communications:
192  *
193  * NORMAL = this is a normal heap entry stating the date to finish transmitting
194  * LATENCY = this is a heap entry to warn us when the latency is payed
195  * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
196  */
197 void Action::heapInsert(double key, Action::Type hat)
198 {
199   type_       = hat;
200   heap_hook_  = get_model()->getActionHeap().emplace(std::make_pair(key, this));
201 }
202
203 void Action::heapRemove()
204 {
205   type_ = Action::Type::NOTSET;
206   if (heap_hook_) {
207     get_model()->getActionHeap().erase(*heap_hook_);
208     clearHeapHandle();
209   }
210 }
211
212 void Action::heapUpdate(double key, Action::Type hat)
213 {
214   type_ = hat;
215   if (heap_hook_) {
216     get_model()->getActionHeap().update(*heap_hook_, std::make_pair(key, this));
217   } else {
218     heap_hook_ = get_model()->getActionHeap().emplace(std::make_pair(key, this));
219   }
220 }
221
222 double Action::get_remains()
223 {
224   XBT_IN("(%p)", this);
225   /* update remains before return it */
226   if (get_model()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
227     update_remains_lazy(surf_get_clock());
228   XBT_OUT();
229   return remains_;
230 }
231
232 void Action::update_max_duration(double delta)
233 {
234   double_update(&max_duration_, delta, sg_surf_precision);
235 }
236 void Action::update_remains(double delta)
237 {
238   double_update(&remains_, delta, sg_maxmin_precision * sg_surf_precision);
239 }
240
241 void Action::set_last_update()
242 {
243   last_update_ = surf_get_clock();
244 }
245
246 } // namespace surf
247 } // namespace simgrid
248 } // namespace simgrid