Logo AND Algorithmique Numérique Distribuée

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