1 /* Copyright (c) 2004-2018. The SimGrid Team. All rights reserved. */
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. */
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"
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");
18 Action::Action(simgrid::kernel::resource::Model* model, double cost, bool failed) : Action(model, cost, failed, nullptr)
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)
26 stateSet_ = getModel()->getFailedActionSet();
28 stateSet_ = getModel()->getRunningActionSet();
30 stateSet_->push_back(*this);
38 void Action::finish(Action::State state)
40 finishTime_ = surf_get_clock();
44 Action::State Action::getState() const
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;
57 void Action::setState(Action::State state)
59 simgrid::xbt::intrusive_erase(*stateSet_, *this);
61 case Action::State::ready:
62 stateSet_ = model_->getReadyActionSet();
64 case Action::State::running:
65 stateSet_ = model_->getRunningActionSet();
67 case Action::State::failed:
68 stateSet_ = model_->getFailedActionSet();
70 case Action::State::done:
71 stateSet_ = model_->getDoneActionSet();
78 stateSet_->push_back(*this);
81 double Action::getBound() const
83 return variable_ ? variable_->get_bound() : 0;
86 void Action::setBound(double bound)
88 XBT_IN("(%p,%g)", this, bound);
90 getModel()->getMaxminSystem()->update_variable_bound(variable_, bound);
92 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate() != surf_get_clock())
93 heapRemove(getModel()->getActionHeap());
97 void Action::setCategory(const char* category)
99 category_ = xbt_strdup(category);
107 void Action::setMaxDuration(double duration)
109 maxDuration_ = duration;
110 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
111 heapRemove(getModel()->getActionHeap());
114 void Action::setSharingWeight(double weight)
116 XBT_IN("(%p,%g)", this, weight);
117 sharingWeight_ = weight;
118 getModel()->getMaxminSystem()->update_variable_weight(getVariable(), weight);
120 if (getModel()->getUpdateMechanism() == UM_LAZY)
121 heapRemove(getModel()->getActionHeap());
125 void Action::cancel()
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());
139 if (stateSetHook_.is_linked())
140 simgrid::xbt::intrusive_erase(*stateSet_, *this);
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);
155 void Action::suspend()
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());
168 suspended_ = SuspendStates::suspended;
173 void Action::resume()
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());
185 bool Action::isSuspended()
187 return suspended_ == SuspendStates::suspended;
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:
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
196 void Action::heapInsert(heap_type& heap, double key, Action::Type hat)
199 heapHandle_ = heap.emplace(std::make_pair(key, this));
202 void Action::heapRemove(heap_type& heap)
204 type_ = Action::Type::NOTSET;
206 heap.erase(*heapHandle_);
211 void Action::heapUpdate(heap_type& heap, double key, Action::Type hat)
215 heap.update(*heapHandle_, std::make_pair(key, this));
217 heapHandle_ = heap.emplace(std::make_pair(key, this));
221 double Action::getRemains()
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());
231 void Action::updateMaxDuration(double delta)
233 double_update(&maxDuration_, delta, sg_surf_precision);
235 void Action::updateRemains(double delta)
237 double_update(&remains_, delta, sg_maxmin_precision * sg_surf_precision);
240 void Action::refreshLastUpdate()
242 lastUpdate_ = surf_get_clock();
246 } // namespace simgrid
247 } // namespace simgrid