X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/08ddd90ede6ae87880ab6aefe213001b224de841..ea74f5d95928a521a588737e81f1de94eef25d19:/include/simgrid/kernel/resource/Action.hpp diff --git a/include/simgrid/kernel/resource/Action.hpp b/include/simgrid/kernel/resource/Action.hpp index d3b7a0497d..8f3f5a90a5 100644 --- a/include/simgrid/kernel/resource/Action.hpp +++ b/include/simgrid/kernel/resource/Action.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2018. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,53 +12,106 @@ #include #include +#include -const int NO_MAX_DURATION = -1.0; +static constexpr double NO_MAX_DURATION = -1.0; namespace simgrid { namespace kernel { namespace resource { -typedef std::pair heap_element_type; -typedef boost::heap::pairing_heap, boost::heap::stable, - boost::heap::compare>> - heap_type; +using heap_element_type = std::pair; +using heap_type = + boost::heap::pairing_heap, boost::heap::stable, + boost::heap::compare>>; + +class XBT_PUBLIC ActionHeap : public heap_type { + friend Action; + +public: + enum class Type { + latency = 100, /* this is a heap entry to warn us when the latency is paid */ + 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(); +}; + +/** @details An action is a consumption on a resource (e.g.: a communication for the network). + * + * It is related (but still different) from activities, that are the stuff on which an actor can be blocked. + * + * - A sequential execution activity encompasses 2 actions: one for the exec itself, + * and a time-limited sleep used as timeout detector. + * - A point-to-point communication activity encompasses 3 actions: one for the comm itself + * (which spans on all links of the path), and one infinite sleep used as failure detector + * on both sender and receiver hosts. + * - Synchronization activities may possibly be connected to no action. -/** @ingroup SURF_interface - * @brief SURF action interface class - * @details An action is an event generated by a resource (e.g.: a communication for the network) */ class XBT_PUBLIC Action { -public: - boost::intrusive::list_member_hook<> modifiedSetHook_; /* Used by the lazy update to list the actions to track */ - bool isLinkedModifiedSet() const { return modifiedSetHook_.is_linked(); } + friend ActionHeap; + + int refcount_ = 1; + double sharing_penalty_ = 1.0; /**< priority (1.0 by default) */ + double max_duration_ = NO_MAX_DURATION; /*< max_duration (may fluctuate until the task is completed) */ + double remains_; /**< How much of that cost remains to be done in the currently running task */ + double start_time_; /**< start time */ + double finish_time_ = -1; /**< finish time (may fluctuate until the task is completed) */ + std::string category_; /**< tracing category for categorized resource utilization monitoring */ - typedef boost::intrusive::member_hook, &Action::modifiedSetHook_> - ActionLmmOptions; - typedef boost::intrusive::list ActionLmmList; + double cost_; + Model* model_; + void* data_ = nullptr; /**< for your convenience */ + activity::ActivityImpl* activity_ = nullptr; + + /* LMM */ + double factor_ = 1.0; /**< Factor for effective rate = var->get_value() * factor_ */ + double last_update_ = 0; + double last_value_ = 0; + lmm::Variable* variable_ = nullptr; + double user_bound_ = -1; - boost::intrusive::list_member_hook<> stateSetHook_; - typedef boost::intrusive::member_hook, &Action::stateSetHook_> - ActionOptions; - typedef boost::intrusive::list ActionList; + ActionHeap::Type type_ = ActionHeap::Type::unset; + boost::optional heap_hook_ = boost::none; + boost::intrusive::list_member_hook<> modified_set_hook_; + boost::intrusive::list_member_hook<> state_set_hook_; + +public: + /* Lazy update needs this Set hook to maintain a list of the tracked actions */ + bool is_within_modified_set() const { return modified_set_hook_.is_linked(); } + using ModifiedSet = boost::intrusive::list< + Action, boost::intrusive::member_hook, &Action::modified_set_hook_>>; + + using StateSet = boost::intrusive::list< + Action, boost::intrusive::member_hook, &Action::state_set_hook_>>; enum class State { - ready = 0, /**< Ready */ - running, /**< Running */ - failed, /**< Task Failure */ - done, /**< Completed */ - to_free, /**< Action to free in next cleanup */ - not_in_the_system /**< Not in the system anymore. Why did you ask ? */ + INITED, /**< Created, but not started yet */ + STARTED, /**< Currently running */ + FAILED, /**< either the resource failed, or the action was canceled */ + FINISHED, /**< Successfully completed */ + IGNORED /**< e.g. failure detectors: infinite sleep actions that are put on resources which failure should get + noticed */ }; enum class SuspendStates { - not_suspended = 0, /**< Action currently not suspended **/ - suspended, - sleeping + RUNNING = 0, /**< Action currently not suspended **/ + SUSPENDED, + SLEEPING }; - enum class Type { LATENCY = 100, MAX_DURATION, NORMAL, NOTSET }; +private: + StateSet* state_set_; + Action::SuspendStates suspended_ = Action::SuspendStates::RUNNING; +public: /** * @brief Action constructor * @@ -66,7 +119,7 @@ public: * @param cost The cost of the Action * @param failed If the action is impossible (e.g.: execute something on a switched off host) */ - Action(simgrid::kernel::resource::Model* model, double cost, bool failed); + Action(Model* model, double cost, bool failed); /** * @brief Action constructor @@ -76,66 +129,75 @@ public: * @param failed If the action is impossible (e.g.: execute something on a switched off host) * @param var The lmm variable associated to this Action if it is part of a LMM component */ - Action(simgrid::kernel::resource::Model* model, double cost, bool failed, kernel::lmm::Variable* var); + Action(Model* model, double cost, bool failed, lmm::Variable* var); + Action(const Action&) = delete; + Action& operator=(const Action&) = delete; virtual ~Action(); /** * @brief Mark that the action is now finished * - * @param state the new [state](\ref simgrid::kernel::resource::Action::State) of the current Action + * @param state the new [state](@ref simgrid::kernel::resource::Action::State) of the current Action */ void finish(Action::State state); - /** @brief Get the [state](\ref simgrid::kernel::resource::Action::State) of the current Action */ - Action::State getState() const; /**< get the state*/ - /** @brief Set the [state](\ref simgrid::kernel::resource::Action::State) of the current Action */ - virtual void setState(Action::State state); + /** @brief Get the [state](@ref simgrid::kernel::resource::Action::State) of the current Action */ + Action::State get_state() const; /**< get the state*/ + /** @brief Set the [state](@ref simgrid::kernel::resource::Action::State) of the current Action */ + virtual void set_state(Action::State state); /** @brief Get the bound of the current Action */ - double getBound() const; + double get_bound() const; /** @brief Set the bound of the current Action */ - void setBound(double bound); + void set_bound(double bound); /** @brief Get the start time of the current action */ - double getStartTime() const { return start_; } + double get_start_time() const { return start_time_; } /** @brief Get the finish time of the current action */ - double getFinishTime() const { return finishTime_; } + double get_finish_time() const { return finish_time_; } /** @brief Get the user data associated to the current action */ - void* getData() const { return data_; } + void* get_data() const { return data_; } /** @brief Set the user data associated to the current action */ - void setData(void* data) { data_ = data; } + void set_data(void* data) { data_ = data; } + + /** @brief Get the user data associated to the current action */ + activity::ActivityImpl* get_activity() const { return activity_; } + /** @brief Set the user data associated to the current action */ + void set_activity(activity::ActivityImpl* activity) { activity_ = activity; } /** @brief Get the cost of the current action */ - double getCost() const { return cost_; } + double get_cost() const { return cost_; } /** @brief Set the cost of the current action */ - void setCost(double cost) { cost_ = cost; } + void set_cost(double cost) { cost_ = cost; } /** @brief Update the maximum duration of the current action * @param delta Amount to remove from the MaxDuration */ - void updateMaxDuration(double delta); + void update_max_duration(double delta); /** @brief Update the remaining time of the current action * @param delta Amount to remove from the remaining time */ - void updateRemains(double delta); + void update_remains(double delta); + + virtual void update_remains_lazy(double now) = 0; /** @brief Set the remaining time of the current action */ - void setRemains(double value) { remains_ = value; } + void set_remains(double value) { remains_ = value; } + /** @brief Get the remaining time of the current action after updating the resource */ - virtual double getRemains(); + virtual double get_remains(); /** @brief Get the remaining time of the current action without updating the resource */ - double getRemainsNoUpdate() const { return remains_; } + double get_remains_no_update() const { return remains_; } /** @brief Set the finish time of the current action */ - void setFinishTime(double value) { finishTime_ = value; } + void set_finish_time(double value) { finish_time_ = value; } /**@brief Add a reference to the current action (refcounting) */ void ref(); /** @brief Unref that action (and destroy it if refcount reaches 0) - * @return true if the action was destroyed and false if someone still has references on it - */ - virtual int unref(); + * @return true if the action was destroyed and false if someone still has references on it */ + bool unref(); /** @brief Cancel the current Action if running */ virtual void cancel(); @@ -146,75 +208,65 @@ public: /** @brief Resume the current Action */ virtual void resume(); + /** @brief Returns true if the current action is suspended */ + bool is_suspended() const { return suspended_ == SuspendStates::SUSPENDED; } /** @brief Returns true if the current action is running */ - virtual bool isSuspended(); + bool is_running() const { return suspended_ == SuspendStates::RUNNING; } /** @brief Get the maximum duration of the current action */ - double getMaxDuration() const { return maxDuration_; } + double get_max_duration() const { return max_duration_; } /** @brief Set the maximum duration of the current Action */ - virtual void setMaxDuration(double duration); + virtual void set_max_duration(double duration); /** @brief Get the tracing category associated to the current action */ - char* getCategory() const { return category_; } + const std::string& get_category() const { return category_; } /** @brief Set the tracing category of the current Action */ - void setCategory(const char* category); + void set_category(const std::string& category) { category_ = category; } - /** @brief Get the priority of the current Action */ - double getPriority() const { return sharingWeight_; }; - /** @brief Set the priority of the current Action */ - virtual void setSharingWeight(double priority); - void setSharingWeightNoUpdate(double weight) { sharingWeight_ = weight; } + /** @brief Get the sharing_penalty (RTT or 1/thread_count) of the current Action */ + double get_sharing_penalty() const { return sharing_penalty_; }; + /** @brief Set the sharing_penalty (RTT or 1/thread_count) of the current Action */ + virtual void set_sharing_penalty(double sharing_penalty); + void set_sharing_penalty_no_update(double sharing_penalty) { sharing_penalty_ = sharing_penalty; } /** @brief Get the state set in which the action is */ - ActionList* getStateSet() const { return stateSet_; }; + StateSet* get_state_set() const { return state_set_; }; - simgrid::kernel::resource::Model* getModel() const { return model_; } + Model* get_model() const { return model_; } -protected: - ActionList* stateSet_; - int refcount_ = 1; + ActionHeap::Type get_type() const { return type_; } -private: - double sharingWeight_ = 1.0; /**< priority (1.0 by default) */ - double maxDuration_ = NO_MAX_DURATION; /*< max_duration (may fluctuate until the task is completed) */ - double remains_; /**< How much of that cost remains to be done in the currently running task */ - double start_; /**< start time */ - char* category_ = nullptr; /**< tracing category for categorized resource utilization monitoring */ - double finishTime_ = - -1; /**< finish time : this is modified during the run and fluctuates until the task is completed */ + lmm::Variable* get_variable() const { return variable_; } + void set_variable(lmm::Variable* var) { variable_ = var; } - double cost_; - simgrid::kernel::resource::Model* model_; - void* data_ = nullptr; /**< for your convenience */ + double get_user_bound() const { return user_bound_; } + void set_user_bound(double bound) { user_bound_ = bound; } - /* LMM */ - double lastUpdate_ = 0; - double lastValue_ = 0; - kernel::lmm::Variable* variable_ = nullptr; - Action::Type type_ = Action::Type::NOTSET; - boost::optional heapHandle_ = boost::none; + double get_last_update() const { return last_update_; } + void set_last_update(); -public: - virtual void updateRemainingLazy(double now) = 0; - void heapInsert(heap_type& heap, double key, Action::Type hat); - void heapRemove(heap_type& heap); - void heapUpdate(heap_type& heap, double key, Action::Type hat); - void clearHeapHandle() { heapHandle_ = boost::none; } - kernel::lmm::Variable* getVariable() const { return variable_; } - void setVariable(kernel::lmm::Variable* var) { variable_ = var; } - double getLastUpdate() const { return lastUpdate_; } - void refreshLastUpdate(); - double getLastValue() const { return lastValue_; } - void setLastValue(double val) { lastValue_ = val; } - Action::Type getType() const { return type_; } - -protected: - Action::SuspendStates suspended_ = Action::SuspendStates::not_suspended; + /** + * @brief Set a factor for this action + * + * Defines a multiplicative factor for the consumption of the underlying resource. + * + * @param factor Multiplicative factor for this action (e.g. 0.97) + */ + void set_rate_factor(double factor) { factor_ = factor; } + /** + * @brief Get the effective consumption rate of the resource + * + * The rate is based on the sharing given by the maxmin system underneath. + * However, it depends on the factor defined for this action. + * + * So, the effective rate is equal to var->get_value() * factor_ + */ + double get_rate() const; + double get_last_value() const { return last_value_; } + void set_last_value(double val) { last_value_ = val; } + void set_suspend_state(Action::SuspendStates state) { suspended_ = state; } }; -typedef Action::ActionList ActionList; -typedef Action::ActionLmmList ActionLmmList; -typedef Action::ActionLmmList* ActionLmmListPtr; } // namespace resource } // namespace kernel } // namespace simgrid