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_time_(surf_get_clock()), cost_(cost), model_(model), variable_(var)
26 state_set_ = get_model()->getFailedActionSet();
28 state_set_ = get_model()->getRunningActionSet();
30 state_set_->push_back(*this);
38 void Action::finish(Action::State state)
40 finish_time_ = surf_get_clock();
45 Action::State Action::get_state() const
47 if (state_set_ == model_->getReadyActionSet())
48 return Action::State::ready;
49 if (state_set_ == model_->getRunningActionSet())
50 return Action::State::running;
51 if (state_set_ == model_->getFailedActionSet())
52 return Action::State::failed;
53 if (state_set_ == model_->getDoneActionSet())
54 return Action::State::done;
55 return Action::State::not_in_the_system;
58 void Action::set_state(Action::State state)
60 simgrid::xbt::intrusive_erase(*state_set_, *this);
62 case Action::State::ready:
63 state_set_ = model_->getReadyActionSet();
65 case Action::State::running:
66 state_set_ = model_->getRunningActionSet();
68 case Action::State::failed:
69 state_set_ = model_->getFailedActionSet();
71 case Action::State::done:
72 state_set_ = model_->getDoneActionSet();
79 state_set_->push_back(*this);
82 double Action::get_bound() const
84 return variable_ ? variable_->get_bound() : 0;
87 void Action::set_bound(double bound)
89 XBT_IN("(%p,%g)", this, bound);
91 get_model()->getMaxminSystem()->update_variable_bound(variable_, bound);
93 if (get_model()->getUpdateMechanism() == UM_LAZY && getLastUpdate() != surf_get_clock())
94 heapRemove(get_model()->getActionHeap());
98 void Action::set_category(const char* category)
100 category_ = xbt_strdup(category);
108 void Action::set_max_duration(double duration)
110 max_duration_ = duration;
111 if (get_model()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
112 heapRemove(get_model()->getActionHeap());
115 void Action::set_priority(double weight)
117 XBT_IN("(%p,%g)", this, weight);
118 sharing_priority_ = weight;
119 get_model()->getMaxminSystem()->update_variable_weight(getVariable(), weight);
121 if (get_model()->getUpdateMechanism() == UM_LAZY)
122 heapRemove(get_model()->getActionHeap());
126 void Action::cancel()
128 set_state(Action::State::failed);
129 if (get_model()->getUpdateMechanism() == UM_LAZY) {
130 if (modified_set_hook_.is_linked())
131 simgrid::xbt::intrusive_erase(*get_model()->getModifiedSet(), *this);
132 heapRemove(get_model()->getActionHeap());
140 if (state_set_hook_.is_linked())
141 simgrid::xbt::intrusive_erase(*state_set_, *this);
143 get_model()->getMaxminSystem()->variable_free(getVariable());
144 if (get_model()->getUpdateMechanism() == UM_LAZY) {
145 /* remove from heap */
146 heapRemove(get_model()->getActionHeap());
147 if (modified_set_hook_.is_linked())
148 simgrid::xbt::intrusive_erase(*get_model()->getModifiedSet(), *this);
156 void Action::suspend()
158 XBT_IN("(%p)", this);
159 if (suspended_ != SuspendStates::sleeping) {
160 get_model()->getMaxminSystem()->update_variable_weight(getVariable(), 0.0);
161 if (get_model()->getUpdateMechanism() == UM_LAZY) {
162 heapRemove(get_model()->getActionHeap());
163 if (get_model()->getUpdateMechanism() == UM_LAZY && state_set_ == get_model()->getRunningActionSet() &&
164 sharing_priority_ > 0) {
165 // If we have a lazy model, we need to update the remaining value accordingly
166 updateRemainingLazy(surf_get_clock());
169 suspended_ = SuspendStates::suspended;
174 void Action::resume()
176 XBT_IN("(%p)", this);
177 if (suspended_ != SuspendStates::sleeping) {
178 get_model()->getMaxminSystem()->update_variable_weight(getVariable(), get_priority());
179 suspended_ = SuspendStates::not_suspended;
180 if (get_model()->getUpdateMechanism() == UM_LAZY)
181 heapRemove(get_model()->getActionHeap());
186 bool Action::isSuspended()
188 return suspended_ == SuspendStates::suspended;
190 /* insert action on heap using a given key and a hat (heap_action_type)
191 * a hat can be of three types for communications:
193 * NORMAL = this is a normal heap entry stating the date to finish transmitting
194 * LATENCY = this is a heap entry to warn us when the latency is payed
195 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
197 void Action::heapInsert(heap_type& heap, double key, Action::Type hat)
200 heap_handle_ = heap.emplace(std::make_pair(key, this));
203 void Action::heapRemove(heap_type& heap)
205 type_ = Action::Type::NOTSET;
207 heap.erase(*heap_handle_);
212 void Action::heapUpdate(heap_type& heap, double key, Action::Type hat)
216 heap.update(*heap_handle_, std::make_pair(key, this));
218 heap_handle_ = heap.emplace(std::make_pair(key, this));
222 double Action::get_remains()
224 XBT_IN("(%p)", this);
225 /* update remains before return it */
226 if (get_model()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
227 updateRemainingLazy(surf_get_clock());
232 void Action::update_max_duration(double delta)
234 double_update(&max_duration_, delta, sg_surf_precision);
236 void Action::update_remains(double delta)
238 double_update(&remains_, delta, sg_maxmin_precision * sg_surf_precision);
241 void Action::refreshLastUpdate()
243 last_update_ = surf_get_clock();
247 } // namespace simgrid
248 } // namespace simgrid