Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
do not load a private header from s/k/resource/ headers
[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_(surf_get_clock()), cost_(cost), model_(model), variable_(var)
24 {
25   if (failed)
26     stateSet_ = getModel()->getFailedActionSet();
27   else
28     stateSet_ = getModel()->getRunningActionSet();
29
30   stateSet_->push_back(*this);
31 }
32
33 Action::~Action()
34 {
35   xbt_free(category_);
36 }
37
38 void Action::finish(Action::State state)
39 {
40   finishTime_ = surf_get_clock();
41   setState(state);
42 }
43
44 Action::State Action::getState() const
45 {
46   if (stateSet_ == model_->getReadyActionSet())
47     return Action::State::ready;
48   if (stateSet_ == model_->getRunningActionSet())
49     return Action::State::running;
50   if (stateSet_ == model_->getFailedActionSet())
51     return Action::State::failed;
52   if (stateSet_ == model_->getDoneActionSet())
53     return Action::State::done;
54   return Action::State::not_in_the_system;
55 }
56
57 void Action::setState(Action::State state)
58 {
59   simgrid::xbt::intrusive_erase(*stateSet_, *this);
60   switch (state) {
61     case Action::State::ready:
62       stateSet_ = model_->getReadyActionSet();
63       break;
64     case Action::State::running:
65       stateSet_ = model_->getRunningActionSet();
66       break;
67     case Action::State::failed:
68       stateSet_ = model_->getFailedActionSet();
69       break;
70     case Action::State::done:
71       stateSet_ = model_->getDoneActionSet();
72       break;
73     default:
74       stateSet_ = nullptr;
75       break;
76   }
77   if (stateSet_)
78     stateSet_->push_back(*this);
79 }
80
81 double Action::getBound() const
82 {
83   return variable_ ? variable_->get_bound() : 0;
84 }
85
86 void Action::setBound(double bound)
87 {
88   XBT_IN("(%p,%g)", this, bound);
89   if (variable_)
90     getModel()->getMaxminSystem()->update_variable_bound(variable_, bound);
91
92   if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate() != surf_get_clock())
93     heapRemove(getModel()->getActionHeap());
94   XBT_OUT();
95 }
96
97 void Action::setCategory(const char* category)
98 {
99   category_ = xbt_strdup(category);
100 }
101
102 void Action::ref()
103 {
104   refcount_++;
105 }
106
107 void Action::setMaxDuration(double duration)
108 {
109   maxDuration_ = duration;
110   if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
111     heapRemove(getModel()->getActionHeap());
112 }
113
114 void Action::setSharingWeight(double weight)
115 {
116   XBT_IN("(%p,%g)", this, weight);
117   sharingWeight_ = weight;
118   getModel()->getMaxminSystem()->update_variable_weight(getVariable(), weight);
119
120   if (getModel()->getUpdateMechanism() == UM_LAZY)
121     heapRemove(getModel()->getActionHeap());
122   XBT_OUT();
123 }
124
125 void Action::cancel()
126 {
127   setState(Action::State::failed);
128   if (getModel()->getUpdateMechanism() == UM_LAZY) {
129     if (modifiedSetHook_.is_linked())
130       simgrid::xbt::intrusive_erase(*getModel()->getModifiedSet(), *this);
131     heapRemove(getModel()->getActionHeap());
132   }
133 }
134
135 int Action::unref()
136 {
137   refcount_--;
138   if (not refcount_) {
139     if (stateSetHook_.is_linked())
140       simgrid::xbt::intrusive_erase(*stateSet_, *this);
141     if (getVariable())
142       getModel()->getMaxminSystem()->variable_free(getVariable());
143     if (getModel()->getUpdateMechanism() == UM_LAZY) {
144       /* remove from heap */
145       heapRemove(getModel()->getActionHeap());
146       if (modifiedSetHook_.is_linked())
147         simgrid::xbt::intrusive_erase(*getModel()->getModifiedSet(), *this);
148     }
149     delete this;
150     return 1;
151   }
152   return 0;
153 }
154
155 void Action::suspend()
156 {
157   XBT_IN("(%p)", this);
158   if (suspended_ != SuspendStates::sleeping) {
159     getModel()->getMaxminSystem()->update_variable_weight(getVariable(), 0.0);
160     if (getModel()->getUpdateMechanism() == UM_LAZY) {
161       heapRemove(getModel()->getActionHeap());
162       if (getModel()->getUpdateMechanism() == UM_LAZY && stateSet_ == getModel()->getRunningActionSet() &&
163           sharingWeight_ > 0) {
164         // If we have a lazy model, we need to update the remaining value accordingly
165         updateRemainingLazy(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     getModel()->getMaxminSystem()->update_variable_weight(getVariable(), getPriority());
178     suspended_ = SuspendStates::not_suspended;
179     if (getModel()->getUpdateMechanism() == UM_LAZY)
180       heapRemove(getModel()->getActionHeap());
181   }
182   XBT_OUT();
183 }
184
185 bool Action::isSuspended()
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(heap_type& heap, double key, Action::Type hat)
197 {
198   type_       = hat;
199   heapHandle_ = heap.emplace(std::make_pair(key, this));
200 }
201
202 void Action::heapRemove(heap_type& heap)
203 {
204   type_ = Action::Type::NOTSET;
205   if (heapHandle_) {
206     heap.erase(*heapHandle_);
207     clearHeapHandle();
208   }
209 }
210
211 void Action::heapUpdate(heap_type& heap, double key, Action::Type hat)
212 {
213   type_ = hat;
214   if (heapHandle_) {
215     heap.update(*heapHandle_, std::make_pair(key, this));
216   } else {
217     heapHandle_ = heap.emplace(std::make_pair(key, this));
218   }
219 }
220
221 double Action::getRemains()
222 {
223   XBT_IN("(%p)", this);
224   /* update remains before return it */
225   if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
226     updateRemainingLazy(surf_get_clock());
227   XBT_OUT();
228   return remains_;
229 }
230
231 void Action::updateMaxDuration(double delta)
232 {
233   double_update(&maxDuration_, delta, sg_surf_precision);
234 }
235 void Action::updateRemains(double delta)
236 {
237   double_update(&remains_, delta, sg_maxmin_precision * sg_surf_precision);
238 }
239
240 void Action::refreshLastUpdate()
241 {
242   lastUpdate_ = surf_get_clock();
243 }
244
245 } // namespace surf
246 } // namespace simgrid
247 } // namespace simgrid