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()->get_failed_action_set();
28 state_set_ = get_model()->get_running_action_set();
30 state_set_->push_back(*this);
35 if (state_set_hook_.is_linked())
36 simgrid::xbt::intrusive_erase(*state_set_, *this);
38 get_model()->get_maxmin_system()->variable_free(get_variable());
40 /* remove from heap on need (ie, if selective update) */
41 get_model()->get_action_heap().remove(this);
42 if (modified_set_hook_.is_linked())
43 simgrid::xbt::intrusive_erase(*get_model()->get_modified_set(), *this);
48 void Action::finish(Action::State state)
50 finish_time_ = surf_get_clock();
55 Action::State Action::get_state() const
57 if (state_set_ == model_->get_ready_action_set())
58 return Action::State::ready;
59 if (state_set_ == model_->get_running_action_set())
60 return Action::State::running;
61 if (state_set_ == model_->get_failed_action_set())
62 return Action::State::failed;
63 if (state_set_ == model_->get_done_action_set())
64 return Action::State::done;
65 return Action::State::not_in_the_system;
68 void Action::set_state(Action::State state)
70 simgrid::xbt::intrusive_erase(*state_set_, *this);
72 case Action::State::ready:
73 state_set_ = model_->get_ready_action_set();
75 case Action::State::running:
76 state_set_ = model_->get_running_action_set();
78 case Action::State::failed:
79 state_set_ = model_->get_failed_action_set();
81 case Action::State::done:
82 state_set_ = model_->get_done_action_set();
89 state_set_->push_back(*this);
92 double Action::get_bound() const
94 return variable_ ? variable_->get_bound() : 0;
97 void Action::set_bound(double bound)
99 XBT_IN("(%p,%g)", this, bound);
101 get_model()->get_maxmin_system()->update_variable_bound(variable_, bound);
103 if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy && get_last_update() != surf_get_clock())
104 get_model()->get_action_heap().remove(this);
108 void Action::set_category(const char* category)
110 category_ = xbt_strdup(category);
118 void Action::set_max_duration(double duration)
120 max_duration_ = duration;
121 if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy) // remove action from the heap
122 get_model()->get_action_heap().remove(this);
125 void Action::set_priority(double weight)
127 XBT_IN("(%p,%g)", this, weight);
128 sharing_priority_ = weight;
129 get_model()->get_maxmin_system()->update_variable_weight(get_variable(), weight);
131 if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy)
132 get_model()->get_action_heap().remove(this);
136 void Action::cancel()
138 set_state(Action::State::failed);
139 if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy) {
140 if (modified_set_hook_.is_linked())
141 simgrid::xbt::intrusive_erase(*get_model()->get_modified_set(), *this);
142 get_model()->get_action_heap().remove(this);
156 void Action::suspend()
158 XBT_IN("(%p)", this);
159 if (suspended_ != SuspendStates::sleeping) {
160 get_model()->get_maxmin_system()->update_variable_weight(get_variable(), 0.0);
161 if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy) {
162 get_model()->get_action_heap().remove(this);
163 if (state_set_ == get_model()->get_running_action_set() && sharing_priority_ > 0) {
164 // If we have a lazy model, we need to update the remaining value accordingly
165 update_remains_lazy(surf_get_clock());
168 suspended_ = SuspendStates::suspended;
173 void Action::resume()
175 XBT_IN("(%p)", this);
176 if (suspended_ != SuspendStates::sleeping) {
177 get_model()->get_maxmin_system()->update_variable_weight(get_variable(), get_priority());
178 suspended_ = SuspendStates::not_suspended;
179 if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy)
180 get_model()->get_action_heap().remove(this);
185 bool Action::is_suspended()
187 return suspended_ == SuspendStates::suspended;
190 double Action::get_remains()
192 XBT_IN("(%p)", this);
193 /* update remains before return it */
194 if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy) /* update remains before return it */
195 update_remains_lazy(surf_get_clock());
200 void Action::update_max_duration(double delta)
202 double_update(&max_duration_, delta, sg_surf_precision);
204 void Action::update_remains(double delta)
206 double_update(&remains_, delta, sg_maxmin_precision * sg_surf_precision);
209 void Action::set_last_update()
211 last_update_ = surf_get_clock();
214 double ActionHeap::top_date() const
218 void ActionHeap::insert(Action* action, double date, ActionHeap::Type type)
220 action->type_ = type;
221 action->heap_hook_ = emplace(std::make_pair(date, action));
223 void ActionHeap::remove(Action* action)
225 action->type_ = ActionHeap::Type::unset;
226 if (action->heap_hook_) {
227 erase(*action->heap_hook_);
228 action->heap_hook_ = boost::none;
231 void ActionHeap::update(Action* action, double date, ActionHeap::Type type)
233 action->type_ = type;
234 if (action->heap_hook_) {
235 heap_type::update(*action->heap_hook_, std::make_pair(date, action));
237 action->heap_hook_ = emplace(std::make_pair(date, action));
240 Action* ActionHeap::pop()
242 Action* action = top().second;
244 action->heap_hook_ = boost::none;
249 } // namespace simgrid
250 } // namespace simgrid