Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
cleanups in Action::State
[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 #include "surf/surf.hpp"
11
12 XBT_LOG_NEW_CATEGORY(kernel, "Logging specific to the internals of SimGrid");
13 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(resource, kernel, "Logging specific to the resources");
14
15 namespace simgrid {
16 namespace kernel {
17 namespace resource {
18
19 Action::Action(simgrid::kernel::resource::Model* model, double cost, bool failed) : Action(model, cost, failed, nullptr)
20 {
21 }
22
23 Action::Action(simgrid::kernel::resource::Model* model, double cost, bool failed, kernel::lmm::Variable* var)
24     : remains_(cost), start_time_(surf_get_clock()), cost_(cost), model_(model), variable_(var)
25 {
26   if (failed)
27     state_set_ = get_model()->get_failed_action_set();
28   else
29     state_set_ = get_model()->get_running_action_set();
30
31   state_set_->push_back(*this);
32 }
33
34 Action::~Action()
35 {
36   if (state_set_hook_.is_linked())
37     simgrid::xbt::intrusive_erase(*state_set_, *this);
38   if (get_variable())
39     get_model()->get_maxmin_system()->variable_free(get_variable());
40
41   /* remove from heap on need (ie, if selective update) */
42   get_model()->get_action_heap().remove(this);
43   if (modified_set_hook_.is_linked())
44     simgrid::xbt::intrusive_erase(*get_model()->get_modified_set(), *this);
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_inited_action_set())
59     return Action::State::inited;
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::ignored;
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::inited:
74       state_set_ = model_->get_inited_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()->get_update_algorithm() == Model::UpdateAlgo::Lazy && get_last_update() != surf_get_clock())
105     get_model()->get_action_heap().remove(this);
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()->get_update_algorithm() == Model::UpdateAlgo::Lazy) // remove action from the heap
123     get_model()->get_action_heap().remove(this);
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()->get_update_algorithm() == Model::UpdateAlgo::Lazy)
133     get_model()->get_action_heap().remove(this);
134   XBT_OUT();
135 }
136
137 void Action::cancel()
138 {
139   set_state(Action::State::failed);
140   if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy) {
141     if (modified_set_hook_.is_linked())
142       simgrid::xbt::intrusive_erase(*get_model()->get_modified_set(), *this);
143     get_model()->get_action_heap().remove(this);
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()->get_update_algorithm() == Model::UpdateAlgo::Lazy) {
163       get_model()->get_action_heap().remove(this);
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()->get_update_algorithm() == Model::UpdateAlgo::Lazy)
181       get_model()->get_action_heap().remove(this);
182   }
183   XBT_OUT();
184 }
185
186 bool Action::is_suspended()
187 {
188   return suspended_ == SuspendStates::suspended;
189 }
190
191 double Action::get_remains()
192 {
193   XBT_IN("(%p)", this);
194   /* update remains before return it */
195   if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy) /* update remains before return it */
196     update_remains_lazy(surf_get_clock());
197   XBT_OUT();
198   return remains_;
199 }
200
201 void Action::update_max_duration(double delta)
202 {
203   double_update(&max_duration_, delta, sg_surf_precision);
204 }
205 void Action::update_remains(double delta)
206 {
207   double_update(&remains_, delta, sg_maxmin_precision * sg_surf_precision);
208 }
209
210 void Action::set_last_update()
211 {
212   last_update_ = surf_get_clock();
213 }
214
215 double ActionHeap::top_date() const
216 {
217   return top().first;
218 }
219 void ActionHeap::insert(Action* action, double date, ActionHeap::Type type)
220 {
221   action->type_      = type;
222   action->heap_hook_ = emplace(std::make_pair(date, action));
223 }
224 void ActionHeap::remove(Action* action)
225 {
226   action->type_ = ActionHeap::Type::unset;
227   if (action->heap_hook_) {
228     erase(*action->heap_hook_);
229     action->heap_hook_ = boost::none;
230   }
231 }
232 void ActionHeap::update(Action* action, double date, ActionHeap::Type type)
233 {
234   action->type_ = type;
235   if (action->heap_hook_) {
236     heap_type::update(*action->heap_hook_, std::make_pair(date, action));
237   } else {
238     action->heap_hook_ = emplace(std::make_pair(date, action));
239   }
240 }
241 Action* ActionHeap::pop()
242 {
243   Action* action = top().second;
244   heap_type::pop();
245   action->heap_hook_ = boost::none;
246   return action;
247 }
248
249 } // namespace surf
250 } // namespace simgrid
251 } // namespace simgrid