boost::heap::compare<simgrid::xbt::HeapComparator<heap_element_type>>>
heap_type;
+typedef std::pair<double, simgrid::kernel::resource::Action*> heap_element_type;
+class XBT_PUBLIC ActionHeap : heap_type {
+ friend Action;
+
+public:
+ enum class Type {
+ latency = 100, /* this is a heap entry to warn us when the latency is payed */
+ max_duration, /* this is a heap entry to warn us when the max_duration limit (timeout) is reached */
+ normal, /* this is a normal heap entry stating the date to finish transmitting */
+ unset
+ };
+
+ double top_date() const;
+ void insert(Action* action, double date, ActionHeap::Type type);
+ void update(Action* action, double date, ActionHeap::Type type);
+ void remove(Action* action);
+ Action* pop();
+ bool empty() const { return heap_type::empty(); }
+};
+
/** @details An action is a consumption on a resource (e.g.: a communication for the network) */
class XBT_PUBLIC Action {
+ friend ActionHeap;
+
public:
/* Lazy update needs this Set hook to maintain a list of the tracked actions */
boost::intrusive::list_member_hook<> modified_set_hook_;
sleeping
};
- enum class Type {
- latency = 100, /* this is a heap entry to warn us when the latency is payed */
- max_duration, /* this is a heap entry to warn us when the max_duration limit (timeout) is reached */
- normal, /* this is a normal heap entry stating the date to finish transmitting */
- unset
- };
-
/**
* @brief Action constructor
*
double last_update_ = 0;
double last_value_ = 0;
kernel::lmm::Variable* variable_ = nullptr;
- Action::Type type_ = Action::Type::unset;
- boost::optional<heap_type::handle_type> heap_hook_ = boost::none;
+
+ ActionHeap::Type type_ = ActionHeap::Type::unset;
+ boost::optional<ActionHeap::handle_type> heap_hook_ = boost::none;
public:
- void heapInsert(double key, Action::Type type);
- void heapRemove();
- void heapUpdate(double key, Action::Type type);
- void heap_clear_handle();
+ ActionHeap::Type get_type() const { return type_; }
lmm::Variable* get_variable() const { return variable_; }
void set_variable(lmm::Variable* var) { variable_ = var; }
double get_last_value() const { return last_value_; }
void set_last_value(double val) { last_value_ = val; }
- Action::Type get_type() const { return type_; }
-
protected:
Action::SuspendStates suspended_ = Action::SuspendStates::not_suspended;
};
UpdateAlgo get_update_algorithm() const { return update_algorithm_; }
/** @brief Get Action heap */
- heap_type& get_action_heap() { return action_heap_; }
-
- double actionHeapTopDate() const { return action_heap_.top().first; }
- Action* actionHeapPop();
+ ActionHeap& get_action_heap() { return action_heap_; }
/**
* @brief Share the resources between the actions
Action::StateSet* running_action_set_ = new Action::StateSet(); /**< Actions in state SURF_ACTION_RUNNING */
Action::StateSet* failed_action_set_ = new Action::StateSet(); /**< Actions in state SURF_ACTION_FAILED */
Action::StateSet* done_action_set_ = new Action::StateSet(); /**< Actions in state SURF_ACTION_DONE */
- heap_type action_heap_;
+ ActionHeap action_heap_;
};
} // namespace resource
get_model()->get_maxmin_system()->variable_free(get_variable());
/* remove from heap on need (ie, if selective update) */
- heapRemove();
+ get_model()->get_action_heap().remove(this);
if (modified_set_hook_.is_linked())
simgrid::xbt::intrusive_erase(*get_model()->get_modified_set(), *this);
get_model()->get_maxmin_system()->update_variable_bound(variable_, bound);
if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy && get_last_update() != surf_get_clock())
- heapRemove();
+ get_model()->get_action_heap().remove(this);
XBT_OUT();
}
{
max_duration_ = duration;
if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy) // remove action from the heap
- heapRemove();
+ get_model()->get_action_heap().remove(this);
}
void Action::set_priority(double weight)
get_model()->get_maxmin_system()->update_variable_weight(get_variable(), weight);
if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy)
- heapRemove();
+ get_model()->get_action_heap().remove(this);
XBT_OUT();
}
if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy) {
if (modified_set_hook_.is_linked())
simgrid::xbt::intrusive_erase(*get_model()->get_modified_set(), *this);
- heapRemove();
+ get_model()->get_action_heap().remove(this);
}
}
if (suspended_ != SuspendStates::sleeping) {
get_model()->get_maxmin_system()->update_variable_weight(get_variable(), 0.0);
if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy) {
- heapRemove();
+ get_model()->get_action_heap().remove(this);
if (state_set_ == get_model()->get_running_action_set() && sharing_priority_ > 0) {
// If we have a lazy model, we need to update the remaining value accordingly
update_remains_lazy(surf_get_clock());
get_model()->get_maxmin_system()->update_variable_weight(get_variable(), get_priority());
suspended_ = SuspendStates::not_suspended;
if (get_model()->get_update_algorithm() == Model::UpdateAlgo::Lazy)
- heapRemove();
+ get_model()->get_action_heap().remove(this);
}
XBT_OUT();
}
{
return suspended_ == SuspendStates::suspended;
}
-/* insert action on heap using a given key and a type */
-void Action::heapInsert(double key, Action::Type type)
-{
- type_ = type;
- heap_hook_ = get_model()->get_action_heap().emplace(std::make_pair(key, this));
-}
-
-void Action::heapRemove()
-{
- type_ = Action::Type::unset;
- if (heap_hook_) {
- get_model()->get_action_heap().erase(*heap_hook_);
- heap_hook_ = boost::none;
- }
-}
-void Action::heap_clear_handle()
-{
- heap_hook_ = boost::none;
-}
-
-void Action::heapUpdate(double key, Action::Type type)
-{
- type_ = type;
- if (heap_hook_) {
- get_model()->get_action_heap().update(*heap_hook_, std::make_pair(key, this));
- } else {
- heap_hook_ = get_model()->get_action_heap().emplace(std::make_pair(key, this));
- }
-}
double Action::get_remains()
{
last_update_ = surf_get_clock();
}
+double ActionHeap::top_date() const
+{
+ return top().first;
+}
+void ActionHeap::insert(Action* action, double date, ActionHeap::Type type)
+{
+ action->type_ = type;
+ action->heap_hook_ = emplace(std::make_pair(date, action));
+}
+void ActionHeap::remove(Action* action)
+{
+ action->type_ = ActionHeap::Type::unset;
+ if (action->heap_hook_) {
+ erase(*action->heap_hook_);
+ action->heap_hook_ = boost::none;
+ }
+}
+void ActionHeap::update(Action* action, double date, ActionHeap::Type type)
+{
+ action->type_ = type;
+ if (action->heap_hook_) {
+ heap_type::update(*action->heap_hook_, std::make_pair(date, action));
+ } else {
+ action->heap_hook_ = emplace(std::make_pair(date, action));
+ }
+}
+Action* ActionHeap::pop()
+{
+ Action* action = top().second;
+ heap_type::pop();
+ action->heap_hook_ = boost::none;
+ return action;
+}
+
} // namespace surf
} // namespace simgrid
} // namespace simgrid
delete maxmin_system_;
}
-Action* Model::actionHeapPop()
-{
- Action* action = action_heap_.top().second;
- action_heap_.pop();
- action->heap_clear_handle();
- return action;
-}
-
Action::ModifiedSet* Model::get_modified_set() const
{
return maxmin_system_->modified_set_;
continue;
/* bogus priority, skip it */
- if (action->get_priority() <= 0 || action->get_type() == Action::Type::latency)
+ if (action->get_priority() <= 0 || action->get_type() == ActionHeap::Type::latency)
continue;
action->update_remains_lazy(now);
action->get_start_time(), min, share, action->get_max_duration());
if (min > -1) {
- action->heapUpdate(min, max_duration_flag ? Action::Type::max_duration : Action::Type::normal);
+ action_heap_.update(action, min, max_duration_flag ? ActionHeap::Type::max_duration : ActionHeap::Type::normal);
XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min, now);
} else
DIE_IMPOSSIBLE;
// hereafter must have already the min value for this resource model
if (not action_heap_.empty()) {
- double min = actionHeapTopDate() - now;
+ double min = action_heap_.top_date() - now;
XBT_DEBUG("minimum with the HEAP %f", min);
return min;
} else {
model()->get_maxmin_system()->update_variable_weight(action->get_variable(), 0.0);
if (model()->get_update_algorithm() == kernel::resource::Model::UpdateAlgo::Lazy) { // remove action from the heap
- action->heapRemove();
+ model()->get_action_heap().remove(action);
// this is necessary for a variable with weight 0 since such variables are ignored in lmm and we need to set its
// max_duration correctly at the next call to share_resources
model()->get_modified_set()->push_front(*action);
void CpuModel::update_actions_state_lazy(double now, double /*delta*/)
{
- while (not get_action_heap().empty() && double_equals(actionHeapTopDate(), now, sg_surf_precision)) {
+ while (not get_action_heap().empty() && double_equals(get_action_heap().top_date(), now, sg_surf_precision)) {
- CpuAction* action = static_cast<CpuAction*>(actionHeapPop());
+ CpuAction* action = static_cast<CpuAction*>(get_action_heap().pop());
XBT_CDEBUG(surf_kernel, "Something happened to action %p", action);
if (TRACE_is_enabled()) {
Cpu* cpu = static_cast<Cpu*>(action->get_variable()->get_constraint(0)->get_id());
/* get the min next event if heap not empty */
if (not get_action_heap().empty())
- min_action_duration = actionHeapTopDate() - now;
+ min_action_duration = get_action_heap().top_date() - now;
XBT_DEBUG("Share resources, min next event date: %f", min_action_duration);
void CpuTiModel::update_actions_state(double now, double /*delta*/)
{
- while (not get_action_heap().empty() && actionHeapTopDate() <= now) {
- CpuTiAction* action = static_cast<CpuTiAction*>(actionHeapPop());
+ while (not get_action_heap().empty() && double_equals(get_action_heap().top_date(), now, sg_surf_precision)) {
+ CpuTiAction* action = static_cast<CpuTiAction*>(get_action_heap().pop());
XBT_DEBUG("Action %p: finish", action);
action->finish(kernel::resource::Action::State::done);
/* update remaining amount of all actions */
action.get_state() == kernel::resource::Action::State::not_in_the_system) {
action.set_finish_time(date);
action.set_state(kernel::resource::Action::State::failed);
- action.heapRemove();
+ model()->get_action_heap().remove(&action);
}
}
}
}
/* add in action heap */
if (min_finish > NO_MAX_DURATION)
- action.heapUpdate(min_finish, kernel::resource::Action::Type::unset);
+ model()->get_action_heap().update(&action, min_finish, kernel::resource::ActionHeap::Type::unset);
else
- action.heapRemove();
+ model()->get_action_heap().remove(&action);
XBT_DEBUG("Update finish time: Cpu(%s) Action: %p, Start Time: %f Finish Time: %f Max duration %f", getCname(),
&action, action.get_start_time(), action.get_finish_time(), action.get_max_duration());
if (action_ti_hook.is_linked())
simgrid::xbt::intrusive_erase(cpu_->action_set_, *this);
/* remove from heap */
- heapRemove();
+ get_model()->get_action_heap().remove(this);
cpu_->set_modified(true);
}
void CpuTiAction::cancel()
{
this->set_state(Action::State::failed);
- heapRemove();
+ get_model()->get_action_heap().remove(this);
cpu_->set_modified(true);
}
XBT_IN("(%p)", this);
if (suspended_ != Action::SuspendStates::sleeping) {
suspended_ = Action::SuspendStates::suspended;
- heapRemove();
+ get_model()->get_action_heap().remove(this);
cpu_->set_modified(true);
}
XBT_OUT();
min_finish = get_finish_time();
/* add in action heap */
- heapUpdate(min_finish, Action::Type::unset);
+ get_model()->get_action_heap().update(this, min_finish, kernel::resource::ActionHeap::Type::unset);
XBT_OUT();
}
void NetworkCm02Model::update_actions_state_lazy(double now, double /*delta*/)
{
- while (not get_action_heap().empty() && double_equals(actionHeapTopDate(), now, sg_surf_precision)) {
+ while (not get_action_heap().empty() && double_equals(get_action_heap().top_date(), now, sg_surf_precision)) {
- NetworkCm02Action* action = static_cast<NetworkCm02Action*>(actionHeapPop());
+ NetworkCm02Action* action = static_cast<NetworkCm02Action*>(get_action_heap().pop());
XBT_DEBUG("Something happened to action %p", action);
if (TRACE_is_enabled()) {
int n = action->get_variable()->get_number_of_constraint();
}
// if I am wearing a latency hat
- if (action->get_type() == kernel::resource::Action::Type::latency) {
+ if (action->get_type() == kernel::resource::ActionHeap::Type::latency) {
XBT_DEBUG("Latency paid for action %p. Activating", action);
get_maxmin_system()->update_variable_weight(action->get_variable(), action->weight_);
- action->heapRemove();
+ get_action_heap().remove(action);
action->set_last_update();
// if I am wearing a max_duration or normal hat
- } else if (action->get_type() == kernel::resource::Action::Type::max_duration ||
- action->get_type() == kernel::resource::Action::Type::normal) {
+ } else if (action->get_type() == kernel::resource::ActionHeap::Type::max_duration ||
+ action->get_type() == kernel::resource::ActionHeap::Type::normal) {
// no need to communicate anymore
// assume that flows that reached max_duration have remaining of 0
XBT_DEBUG("Action %p finished", action);
action->finish(kernel::resource::Action::State::done);
- action->heapRemove();
+ get_action_heap().remove(action);
}
}
}
action->set_variable(get_maxmin_system()->variable_new(action, 0.0, -1.0, constraints_per_variable));
if (get_update_algorithm() == kernel::resource::Model::UpdateAlgo::Lazy) {
// add to the heap the event when the latency is payed
- XBT_DEBUG("Added action (%p) one latency event at date %f", action, action->latency_ + action->get_last_update());
- action->heapInsert(action->latency_ + action->get_last_update(), route.empty()
- ? kernel::resource::Action::Type::normal
- : kernel::resource::Action::Type::latency);
+ double date = action->latency_ + action->get_last_update();
+ kernel::resource::ActionHeap::Type type;
+ if (route.empty())
+ type = kernel::resource::ActionHeap::Type::normal;
+ else
+ type = kernel::resource::ActionHeap::Type::latency;
+
+ XBT_DEBUG("Added action (%p) one latency event at date %f", action, date);
+ get_action_heap().insert(action, date, type);
}
} else
action->set_variable(get_maxmin_system()->variable_new(action, 1.0, -1.0, constraints_per_variable));
if ((get_remains_no_update() <= 0 && (get_variable()->get_weight() > 0)) ||
((max_duration > NO_MAX_DURATION) && (max_duration <= 0))) {
finish(Action::State::done);
- heapRemove();
+ get_model()->get_action_heap().remove(this);
}
set_last_update();