Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[KERNEL] Fix grammar in a comment
[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_started_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_started_action_set())
61     return Action::State::STARTED;
62   if (state_set_ == model_->get_failed_action_set())
63     return Action::State::FAILED;
64   if (state_set_ == model_->get_finished_action_set())
65     return Action::State::FINISHED;
66   if (state_set_ == model_->get_ignored_action_set())
67     return Action::State::IGNORED;
68   THROW_IMPOSSIBLE;
69 }
70
71 void Action::set_state(Action::State state)
72 {
73   simgrid::xbt::intrusive_erase(*state_set_, *this);
74   switch (state) {
75     case Action::State::INITED:
76       state_set_ = model_->get_inited_action_set();
77       break;
78     case Action::State::STARTED:
79       state_set_ = model_->get_started_action_set();
80       break;
81     case Action::State::FAILED:
82       state_set_ = model_->get_failed_action_set();
83       break;
84     case Action::State::FINISHED:
85       state_set_ = model_->get_finished_action_set();
86       break;
87     case Action::State::IGNORED:
88       state_set_ = model_->get_ignored_action_set();
89       break;
90     default:
91       state_set_ = nullptr;
92       break;
93   }
94   if (state_set_)
95     state_set_->push_back(*this);
96 }
97
98 double Action::get_bound() const
99 {
100   return variable_ ? variable_->get_bound() : 0;
101 }
102
103 void Action::set_bound(double bound)
104 {
105   XBT_IN("(%p,%g)", this, bound);
106   if (variable_)
107     get_model()->get_maxmin_system()->update_variable_bound(variable_, bound);
108
109   if (get_model()->get_update_algorithm() == Model::UpdateAlgo::LAZY && get_last_update() != surf_get_clock())
110     get_model()->get_action_heap().remove(this);
111   XBT_OUT();
112 }
113
114 void Action::set_category(const char* category)
115 {
116   category_ = xbt_strdup(category);
117 }
118
119 void Action::ref()
120 {
121   refcount_++;
122 }
123
124 void Action::set_max_duration(double duration)
125 {
126   max_duration_ = duration;
127   if (get_model()->get_update_algorithm() == Model::UpdateAlgo::LAZY) // remove action from the heap
128     get_model()->get_action_heap().remove(this);
129 }
130
131 void Action::set_priority(double weight)
132 {
133   XBT_IN("(%p,%g)", this, weight);
134   sharing_priority_ = weight;
135   get_model()->get_maxmin_system()->update_variable_weight(get_variable(), weight);
136
137   if (get_model()->get_update_algorithm() == Model::UpdateAlgo::LAZY)
138     get_model()->get_action_heap().remove(this);
139   XBT_OUT();
140 }
141
142 void Action::cancel()
143 {
144   set_state(Action::State::FAILED);
145   if (get_model()->get_update_algorithm() == Model::UpdateAlgo::LAZY) {
146     if (modified_set_hook_.is_linked())
147       simgrid::xbt::intrusive_erase(*get_model()->get_modified_set(), *this);
148     get_model()->get_action_heap().remove(this);
149   }
150 }
151
152 bool Action::unref()
153 {
154   refcount_--;
155   if (not refcount_) {
156     delete this;
157     return true;
158   }
159   return false;
160 }
161
162 void Action::suspend()
163 {
164   XBT_IN("(%p)", this);
165   if (suspended_ != SuspendStates::sleeping) {
166     get_model()->get_maxmin_system()->update_variable_weight(get_variable(), 0.0);
167     if (get_model()->get_update_algorithm() == Model::UpdateAlgo::LAZY) {
168       get_model()->get_action_heap().remove(this);
169       if (state_set_ == get_model()->get_started_action_set() && sharing_priority_ > 0) {
170         // If we have a lazy model, we need to update the remaining value accordingly
171         update_remains_lazy(surf_get_clock());
172       }
173     }
174     suspended_ = SuspendStates::suspended;
175   }
176   XBT_OUT();
177 }
178
179 void Action::resume()
180 {
181   XBT_IN("(%p)", this);
182   if (suspended_ != SuspendStates::sleeping) {
183     get_model()->get_maxmin_system()->update_variable_weight(get_variable(), get_priority());
184     suspended_ = SuspendStates::not_suspended;
185     if (get_model()->get_update_algorithm() == Model::UpdateAlgo::LAZY)
186       get_model()->get_action_heap().remove(this);
187   }
188   XBT_OUT();
189 }
190
191 bool Action::is_suspended()
192 {
193   return suspended_ == SuspendStates::suspended;
194 }
195
196 double Action::get_remains()
197 {
198   XBT_IN("(%p)", this);
199   /* update remains before returning it */
200   if (get_model()->get_update_algorithm() == Model::UpdateAlgo::LAZY) /* update remains before return it */
201     update_remains_lazy(surf_get_clock());
202   XBT_OUT();
203   return remains_;
204 }
205
206 void Action::update_max_duration(double delta)
207 {
208   double_update(&max_duration_, delta, sg_surf_precision);
209 }
210 void Action::update_remains(double delta)
211 {
212   double_update(&remains_, delta, sg_maxmin_precision * sg_surf_precision);
213 }
214
215 void Action::set_last_update()
216 {
217   last_update_ = surf_get_clock();
218 }
219
220 double ActionHeap::top_date() const
221 {
222   return top().first;
223 }
224 void ActionHeap::insert(Action* action, double date, ActionHeap::Type type)
225 {
226   action->type_      = type;
227   action->heap_hook_ = emplace(std::make_pair(date, action));
228 }
229 void ActionHeap::remove(Action* action)
230 {
231   action->type_ = ActionHeap::Type::unset;
232   if (action->heap_hook_) {
233     erase(*action->heap_hook_);
234     action->heap_hook_ = boost::none;
235   }
236 }
237 void ActionHeap::update(Action* action, double date, ActionHeap::Type type)
238 {
239   action->type_ = type;
240   if (action->heap_hook_) {
241     heap_type::update(*action->heap_hook_, std::make_pair(date, action));
242   } else {
243     action->heap_hook_ = emplace(std::make_pair(date, action));
244   }
245 }
246 Action* ActionHeap::pop()
247 {
248   Action* action = top().second;
249   heap_type::pop();
250   action->heap_hook_ = boost::none;
251   return action;
252 }
253
254 } // namespace surf
255 } // namespace simgrid
256 } // namespace simgrid