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 "src/kernel/resource/Action.hpp"
7 #include "src/kernel/lmm/maxmin.hpp"
8 #include "src/kernel/resource/Model.hpp"
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");
17 Action::Action(simgrid::kernel::resource::Model* model, double cost, bool failed) : Action(model, cost, failed, nullptr)
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)
25 stateSet_ = getModel()->getFailedActionSet();
27 stateSet_ = getModel()->getRunningActionSet();
29 stateSet_->push_back(*this);
37 void Action::finish(Action::State state)
39 finishTime_ = surf_get_clock();
43 Action::State Action::getState() const
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;
56 void Action::setState(Action::State state)
58 simgrid::xbt::intrusive_erase(*stateSet_, *this);
60 case Action::State::ready:
61 stateSet_ = model_->getReadyActionSet();
63 case Action::State::running:
64 stateSet_ = model_->getRunningActionSet();
66 case Action::State::failed:
67 stateSet_ = model_->getFailedActionSet();
69 case Action::State::done:
70 stateSet_ = model_->getDoneActionSet();
77 stateSet_->push_back(*this);
80 double Action::getBound() const
82 return variable_ ? variable_->get_bound() : 0;
85 void Action::setBound(double bound)
87 XBT_IN("(%p,%g)", this, bound);
89 getModel()->getMaxminSystem()->update_variable_bound(variable_, bound);
91 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate() != surf_get_clock())
92 heapRemove(getModel()->getActionHeap());
96 void Action::setCategory(const char* category)
98 category_ = xbt_strdup(category);
106 void Action::setMaxDuration(double duration)
108 maxDuration_ = duration;
109 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
110 heapRemove(getModel()->getActionHeap());
113 void Action::setSharingWeight(double weight)
115 XBT_IN("(%p,%g)", this, weight);
116 sharingWeight_ = weight;
117 getModel()->getMaxminSystem()->update_variable_weight(getVariable(), weight);
119 if (getModel()->getUpdateMechanism() == UM_LAZY)
120 heapRemove(getModel()->getActionHeap());
124 void Action::cancel()
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());
138 if (stateSetHook_.is_linked())
139 simgrid::xbt::intrusive_erase(*stateSet_, *this);
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);
154 void Action::suspend()
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());
167 suspended_ = SuspendStates::suspended;
172 void Action::resume()
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());
184 bool Action::isSuspended()
186 return suspended_ == SuspendStates::suspended;
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:
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
195 void Action::heapInsert(heap_type& heap, double key, Action::Type hat)
198 heapHandle_ = heap.emplace(std::make_pair(key, this));
201 void Action::heapRemove(heap_type& heap)
203 type_ = Action::Type::NOTSET;
205 heap.erase(*heapHandle_);
210 void Action::heapUpdate(heap_type& heap, double key, Action::Type hat)
214 heap.update(*heapHandle_, std::make_pair(key, this));
216 heapHandle_ = heap.emplace(std::make_pair(key, this));
220 double Action::getRemains()
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());
231 } // namespace simgrid
232 } // namespace simgrid