Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Make field private.
[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 "src/kernel/resource/Action.hpp"
7 #include "src/kernel/lmm/maxmin.hpp"
8 #include "src/kernel/resource/Model.hpp"
9
10 XBT_LOG_NEW_CATEGORY(kernel, "Logging specific to the internals of SimGrid");
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(resource, kernel, "Logging specific to the resources");
12
13 namespace simgrid {
14 namespace kernel {
15 namespace resource {
16
17 Action::Action(simgrid::kernel::resource::Model* model, double cost, bool failed) : Action(model, cost, failed, nullptr)
18 {
19 }
20
21 Action::Action(simgrid::kernel::resource::Model* model, double cost, bool failed, kernel::lmm::Variable* var)
22     : remains_(cost), start_(surf_get_clock()), cost_(cost), model_(model), variable_(var)
23 {
24   if (failed)
25     stateSet_ = getModel()->getFailedActionSet();
26   else
27     stateSet_ = getModel()->getRunningActionSet();
28
29   stateSet_->push_back(*this);
30 }
31
32 Action::~Action()
33 {
34   xbt_free(category_);
35 }
36
37 void Action::finish(Action::State state)
38 {
39   finishTime_ = surf_get_clock();
40   setState(state);
41 }
42
43 Action::State Action::getState() const
44 {
45   if (stateSet_ == model_->getReadyActionSet())
46     return Action::State::ready;
47   if (stateSet_ == model_->getRunningActionSet())
48     return Action::State::running;
49   if (stateSet_ == model_->getFailedActionSet())
50     return Action::State::failed;
51   if (stateSet_ == model_->getDoneActionSet())
52     return Action::State::done;
53   return Action::State::not_in_the_system;
54 }
55
56 void Action::setState(Action::State state)
57 {
58   simgrid::xbt::intrusive_erase(*stateSet_, *this);
59   switch (state) {
60     case Action::State::ready:
61       stateSet_ = model_->getReadyActionSet();
62       break;
63     case Action::State::running:
64       stateSet_ = model_->getRunningActionSet();
65       break;
66     case Action::State::failed:
67       stateSet_ = model_->getFailedActionSet();
68       break;
69     case Action::State::done:
70       stateSet_ = model_->getDoneActionSet();
71       break;
72     default:
73       stateSet_ = nullptr;
74       break;
75   }
76   if (stateSet_)
77     stateSet_->push_back(*this);
78 }
79
80 double Action::getBound() const
81 {
82   return variable_ ? variable_->get_bound() : 0;
83 }
84
85 void Action::setBound(double bound)
86 {
87   XBT_IN("(%p,%g)", this, bound);
88   if (variable_)
89     getModel()->getMaxminSystem()->update_variable_bound(variable_, bound);
90
91   if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate() != surf_get_clock())
92     heapRemove(getModel()->getActionHeap());
93   XBT_OUT();
94 }
95
96 void Action::setCategory(const char* category)
97 {
98   category_ = xbt_strdup(category);
99 }
100
101 void Action::ref()
102 {
103   refcount_++;
104 }
105
106 void Action::setMaxDuration(double duration)
107 {
108   maxDuration_ = duration;
109   if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
110     heapRemove(getModel()->getActionHeap());
111 }
112
113 void Action::setSharingWeight(double weight)
114 {
115   XBT_IN("(%p,%g)", this, weight);
116   sharingWeight_ = weight;
117   getModel()->getMaxminSystem()->update_variable_weight(getVariable(), weight);
118
119   if (getModel()->getUpdateMechanism() == UM_LAZY)
120     heapRemove(getModel()->getActionHeap());
121   XBT_OUT();
122 }
123
124 void Action::cancel()
125 {
126   setState(Action::State::failed);
127   if (getModel()->getUpdateMechanism() == UM_LAZY) {
128     if (modifiedSetHook_.is_linked())
129       simgrid::xbt::intrusive_erase(*getModel()->getModifiedSet(), *this);
130     heapRemove(getModel()->getActionHeap());
131   }
132 }
133
134 int Action::unref()
135 {
136   refcount_--;
137   if (not refcount_) {
138     if (stateSetHook_.is_linked())
139       simgrid::xbt::intrusive_erase(*stateSet_, *this);
140     if (getVariable())
141       getModel()->getMaxminSystem()->variable_free(getVariable());
142     if (getModel()->getUpdateMechanism() == UM_LAZY) {
143       /* remove from heap */
144       heapRemove(getModel()->getActionHeap());
145       if (modifiedSetHook_.is_linked())
146         simgrid::xbt::intrusive_erase(*getModel()->getModifiedSet(), *this);
147     }
148     delete this;
149     return 1;
150   }
151   return 0;
152 }
153
154 void Action::suspend()
155 {
156   XBT_IN("(%p)", this);
157   if (suspended_ != SuspendStates::sleeping) {
158     getModel()->getMaxminSystem()->update_variable_weight(getVariable(), 0.0);
159     if (getModel()->getUpdateMechanism() == UM_LAZY) {
160       heapRemove(getModel()->getActionHeap());
161       if (getModel()->getUpdateMechanism() == UM_LAZY && stateSet_ == getModel()->getRunningActionSet() &&
162           sharingWeight_ > 0) {
163         // If we have a lazy model, we need to update the remaining value accordingly
164         updateRemainingLazy(surf_get_clock());
165       }
166     }
167     suspended_ = SuspendStates::suspended;
168   }
169   XBT_OUT();
170 }
171
172 void Action::resume()
173 {
174   XBT_IN("(%p)", this);
175   if (suspended_ != SuspendStates::sleeping) {
176     getModel()->getMaxminSystem()->update_variable_weight(getVariable(), getPriority());
177     suspended_ = SuspendStates::not_suspended;
178     if (getModel()->getUpdateMechanism() == UM_LAZY)
179       heapRemove(getModel()->getActionHeap());
180   }
181   XBT_OUT();
182 }
183
184 bool Action::isSuspended()
185 {
186   return suspended_ == SuspendStates::suspended;
187 }
188 /* insert action on heap using a given key and a hat (heap_action_type)
189  * a hat can be of three types for communications:
190  *
191  * NORMAL = this is a normal heap entry stating the date to finish transmitting
192  * LATENCY = this is a heap entry to warn us when the latency is payed
193  * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
194  */
195 void Action::heapInsert(heap_type& heap, double key, Action::Type hat)
196 {
197   type_       = hat;
198   heapHandle_ = heap.emplace(std::make_pair(key, this));
199 }
200
201 void Action::heapRemove(heap_type& heap)
202 {
203   type_ = Action::Type::NOTSET;
204   if (heapHandle_) {
205     heap.erase(*heapHandle_);
206     clearHeapHandle();
207   }
208 }
209
210 void Action::heapUpdate(heap_type& heap, double key, Action::Type hat)
211 {
212   type_ = hat;
213   if (heapHandle_) {
214     heap.update(*heapHandle_, std::make_pair(key, this));
215   } else {
216     heapHandle_ = heap.emplace(std::make_pair(key, this));
217   }
218 }
219
220 double Action::getRemains()
221 {
222   XBT_IN("(%p)", this);
223   /* update remains before return it */
224   if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
225     updateRemainingLazy(surf_get_clock());
226   XBT_OUT();
227   return remains_;
228 }
229
230 } // namespace surf
231 } // namespace simgrid
232 } // namespace simgrid