From: Martin Quinson Date: Sun, 11 Mar 2018 18:43:24 +0000 (+0100) Subject: further split the kernel/resource module in separate files X-Git-Tag: v3.19~91 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/86e534066dafbcbb2284a75ad76d8258a329d226 further split the kernel/resource module in separate files --- diff --git a/src/kernel/activity/CommImpl.cpp b/src/kernel/activity/CommImpl.cpp index c4f8b52cbb..98be4746d6 100644 --- a/src/kernel/activity/CommImpl.cpp +++ b/src/kernel/activity/CommImpl.cpp @@ -4,6 +4,7 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/kernel/activity/CommImpl.hpp" +#include "src/kernel/resource/Action.hpp" #include "simgrid/modelchecker.h" #include "src/mc/mc_replay.hpp" diff --git a/src/kernel/activity/SleepImpl.cpp b/src/kernel/activity/SleepImpl.cpp index bc34a7858e..c4a452b39e 100644 --- a/src/kernel/activity/SleepImpl.cpp +++ b/src/kernel/activity/SleepImpl.cpp @@ -7,6 +7,7 @@ #include "src/kernel/activity/SleepImpl.hpp" #include "src/kernel/context/Context.hpp" +#include "src/kernel/resource/Action.hpp" #include "src/simix/ActorImpl.hpp" #include "src/simix/popping_private.hpp" diff --git a/src/kernel/activity/SynchroIo.cpp b/src/kernel/activity/SynchroIo.cpp index 9001cf9c57..abd8302636 100644 --- a/src/kernel/activity/SynchroIo.cpp +++ b/src/kernel/activity/SynchroIo.cpp @@ -4,6 +4,7 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/kernel/activity/SynchroIo.hpp" +#include "src/kernel/resource/Action.hpp" #include "src/simix/smx_private.hpp" #include "src/surf/surf_interface.hpp" diff --git a/src/kernel/activity/SynchroRaw.cpp b/src/kernel/activity/SynchroRaw.cpp index 0b11a05da3..e6db37c92f 100644 --- a/src/kernel/activity/SynchroRaw.cpp +++ b/src/kernel/activity/SynchroRaw.cpp @@ -4,6 +4,7 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/kernel/activity/SynchroRaw.hpp" +#include "src/kernel/resource/Action.hpp" #include "src/simix/smx_synchro_private.hpp" #include "src/surf/surf_interface.hpp" diff --git a/src/kernel/lmm/maxmin.hpp b/src/kernel/lmm/maxmin.hpp index f3ea120a37..6c08ad07d6 100644 --- a/src/kernel/lmm/maxmin.hpp +++ b/src/kernel/lmm/maxmin.hpp @@ -7,6 +7,7 @@ #define SURF_MAXMIN_HPP #include "src/internal_config.h" +#include "src/kernel/resource/Action.hpp" #include "src/surf/surf_interface.hpp" #include "surf/surf.hpp" #include "xbt/asserts.h" diff --git a/src/kernel/resource/Action.cpp b/src/kernel/resource/Action.cpp new file mode 100644 index 0000000000..69c372971c --- /dev/null +++ b/src/kernel/resource/Action.cpp @@ -0,0 +1,228 @@ +/* Copyright (c) 2004-2018. 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. */ + +#include "src/kernel/resource/Action.hpp" +#include "src/kernel/lmm/maxmin.hpp" +#include "src/kernel/resource/Model.hpp" + +XBT_LOG_NEW_CATEGORY(kernel, "Logging specific to the internals of SimGrid"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(resource, kernel, "Logging specific to the resources"); + +namespace simgrid { +namespace surf { + +Action::Action(simgrid::surf::Model* model, double cost, bool failed) : Action(model, cost, failed, nullptr) {} + +Action::Action(simgrid::surf::Model* model, double cost, bool failed, kernel::lmm::Variable* var) + : remains_(cost), start_(surf_get_clock()), cost_(cost), model_(model), variable_(var) +{ + if (failed) + stateSet_ = getModel()->getFailedActionSet(); + else + stateSet_ = getModel()->getRunningActionSet(); + + stateSet_->push_back(*this); +} + +Action::~Action() +{ + xbt_free(category_); +} + +void Action::finish(Action::State state) +{ + finishTime_ = surf_get_clock(); + setState(state); +} + +Action::State Action::getState() const +{ + if (stateSet_ == model_->getReadyActionSet()) + return Action::State::ready; + if (stateSet_ == model_->getRunningActionSet()) + return Action::State::running; + if (stateSet_ == model_->getFailedActionSet()) + return Action::State::failed; + if (stateSet_ == model_->getDoneActionSet()) + return Action::State::done; + return Action::State::not_in_the_system; +} + +void Action::setState(Action::State state) +{ + simgrid::xbt::intrusive_erase(*stateSet_, *this); + switch (state) { + case Action::State::ready: + stateSet_ = model_->getReadyActionSet(); + break; + case Action::State::running: + stateSet_ = model_->getRunningActionSet(); + break; + case Action::State::failed: + stateSet_ = model_->getFailedActionSet(); + break; + case Action::State::done: + stateSet_ = model_->getDoneActionSet(); + break; + default: + stateSet_ = nullptr; + break; + } + if (stateSet_) + stateSet_->push_back(*this); +} + +double Action::getBound() const +{ + return variable_ ? variable_->get_bound() : 0; +} + +void Action::setBound(double bound) +{ + XBT_IN("(%p,%g)", this, bound); + if (variable_) + getModel()->getMaxminSystem()->update_variable_bound(variable_, bound); + + if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate() != surf_get_clock()) + heapRemove(getModel()->getActionHeap()); + XBT_OUT(); +} + +void Action::setCategory(const char* category) +{ + category_ = xbt_strdup(category); +} + +void Action::ref() +{ + refcount_++; +} + +void Action::setMaxDuration(double duration) +{ + maxDuration_ = duration; + if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap + heapRemove(getModel()->getActionHeap()); +} + +void Action::setSharingWeight(double weight) +{ + XBT_IN("(%p,%g)", this, weight); + sharingWeight_ = weight; + getModel()->getMaxminSystem()->update_variable_weight(getVariable(), weight); + + if (getModel()->getUpdateMechanism() == UM_LAZY) + heapRemove(getModel()->getActionHeap()); + XBT_OUT(); +} + +void Action::cancel() +{ + setState(Action::State::failed); + if (getModel()->getUpdateMechanism() == UM_LAZY) { + if (modifiedSetHook_.is_linked()) + simgrid::xbt::intrusive_erase(*getModel()->getModifiedSet(), *this); + heapRemove(getModel()->getActionHeap()); + } +} + +int Action::unref() +{ + refcount_--; + if (not refcount_) { + if (stateSetHook_.is_linked()) + simgrid::xbt::intrusive_erase(*stateSet_, *this); + if (getVariable()) + getModel()->getMaxminSystem()->variable_free(getVariable()); + if (getModel()->getUpdateMechanism() == UM_LAZY) { + /* remove from heap */ + heapRemove(getModel()->getActionHeap()); + if (modifiedSetHook_.is_linked()) + simgrid::xbt::intrusive_erase(*getModel()->getModifiedSet(), *this); + } + delete this; + return 1; + } + return 0; +} + +void Action::suspend() +{ + XBT_IN("(%p)", this); + if (suspended_ != SuspendStates::sleeping) { + getModel()->getMaxminSystem()->update_variable_weight(getVariable(), 0.0); + if (getModel()->getUpdateMechanism() == UM_LAZY) { + heapRemove(getModel()->getActionHeap()); + if (getModel()->getUpdateMechanism() == UM_LAZY && stateSet_ == getModel()->getRunningActionSet() && + sharingWeight_ > 0) { + // If we have a lazy model, we need to update the remaining value accordingly + updateRemainingLazy(surf_get_clock()); + } + } + suspended_ = SuspendStates::suspended; + } + XBT_OUT(); +} + +void Action::resume() +{ + XBT_IN("(%p)", this); + if (suspended_ != SuspendStates::sleeping) { + getModel()->getMaxminSystem()->update_variable_weight(getVariable(), getPriority()); + suspended_ = SuspendStates::not_suspended; + if (getModel()->getUpdateMechanism() == UM_LAZY) + heapRemove(getModel()->getActionHeap()); + } + XBT_OUT(); +} + +bool Action::isSuspended() +{ + return suspended_ == SuspendStates::suspended; +} +/* insert action on heap using a given key and a hat (heap_action_type) + * a hat can be of three types for communications: + * + * NORMAL = this is a normal heap entry stating the date to finish transmitting + * LATENCY = 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 is reached + */ +void Action::heapInsert(heap_type& heap, double key, Action::Type hat) +{ + type_ = hat; + heapHandle_ = heap.emplace(std::make_pair(key, this)); +} + +void Action::heapRemove(heap_type& heap) +{ + type_ = Action::Type::NOTSET; + if (heapHandle_) { + heap.erase(*heapHandle_); + clearHeapHandle(); + } +} + +void Action::heapUpdate(heap_type& heap, double key, Action::Type hat) +{ + type_ = hat; + if (heapHandle_) { + heap.update(*heapHandle_, std::make_pair(key, this)); + } else { + heapHandle_ = heap.emplace(std::make_pair(key, this)); + } +} + +double Action::getRemains() +{ + XBT_IN("(%p)", this); + /* update remains before return it */ + if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */ + updateRemainingLazy(surf_get_clock()); + XBT_OUT(); + return remains_; +} + +} // namespace surf +} // namespace simgrid diff --git a/src/kernel/resource/Action.hpp b/src/kernel/resource/Action.hpp new file mode 100644 index 0000000000..c5595b82af --- /dev/null +++ b/src/kernel/resource/Action.hpp @@ -0,0 +1,213 @@ +/* Copyright (c) 2004-2018. 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. */ + +#ifndef SIMGRID_KERNEL_RESOURCE_ACTION_HPP +#define SIMGRID_KERNEL_RESOURCE_ACTION_HPP + +#include "src/surf/surf_interface.hpp" + +namespace simgrid { +namespace surf { + +typedef std::pair heap_element_type; +typedef boost::heap::pairing_heap, boost::heap::stable, + boost::heap::compare>> + heap_type; + +/** @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) + */ +XBT_PUBLIC_CLASS 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(); } + + typedef boost::intrusive::member_hook, &Action::modifiedSetHook_> + ActionLmmOptions; + typedef boost::intrusive::list ActionLmmList; + + boost::intrusive::list_member_hook<> stateSetHook_; + typedef boost::intrusive::member_hook, &Action::stateSetHook_> + ActionOptions; + typedef boost::intrusive::list ActionList; + + 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 ? */ + }; + + enum class SuspendStates { + not_suspended = 0, /**< Action currently not suspended **/ + suspended, + sleeping + }; + + enum class Type { LATENCY = 100, MAX_DURATION, NORMAL, NOTSET }; + + /** + * @brief Action constructor + * + * @param model The Model associated to this Action + * @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::surf::Model * model, double cost, bool failed); + + /** + * @brief Action constructor + * + * @param model The Model associated to this Action + * @param cost The cost of the Action + * @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::surf::Model * model, double cost, bool failed, kernel::lmm::Variable* var); + + virtual ~Action(); + + /** + * @brief Mark that the action is now finished + * + * @param state the new [state](\ref simgrid::surf::Action::State) of the current Action + */ + void finish(Action::State state); + + /** @brief Get the [state](\ref simgrid::surf::Action::State) of the current Action */ + Action::State getState() const; /**< get the state*/ + /** @brief Set the [state](\ref simgrid::surf::Action::State) of the current Action */ + virtual void setState(Action::State state); + + /** @brief Get the bound of the current Action */ + double getBound() const; + /** @brief Set the bound of the current Action */ + void setBound(double bound); + + /** @brief Get the start time of the current action */ + double getStartTime() const { return start_; } + /** @brief Get the finish time of the current action */ + double getFinishTime() const { return finishTime_; } + + /** @brief Get the user data associated to the current action */ + void* getData() const { return data_; } + /** @brief Set the user data associated to the current action */ + void setData(void* data) { data_ = data; } + + /** @brief Get the cost of the current action */ + double getCost() const { return cost_; } + /** @brief Set the cost of the current action */ + void setCost(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) { double_update(&maxDuration_, delta, sg_surf_precision); } + + /** @brief Update the remaining time of the current action + * @param delta Amount to remove from the remaining time */ + void updateRemains(double delta) { double_update(&remains_, delta, sg_maxmin_precision * sg_surf_precision); } + + /** @brief Set the remaining time of the current action */ + void setRemains(double value) { remains_ = value; } + /** @brief Get the remaining time of the current action after updating the resource */ + virtual double getRemains(); + /** @brief Get the remaining time of the current action without updating the resource */ + double getRemainsNoUpdate() const { return remains_; } + + /** @brief Set the finish time of the current action */ + void setFinishTime(double value) { finishTime_ = 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(); + + /** @brief Cancel the current Action if running */ + virtual void cancel(); + + /** @brief Suspend the current Action */ + virtual void suspend(); + + /** @brief Resume the current Action */ + virtual void resume(); + + /** @brief Returns true if the current action is running */ + virtual bool isSuspended(); + + /** @brief Get the maximum duration of the current action */ + double getMaxDuration() const { return maxDuration_; } + /** @brief Set the maximum duration of the current Action */ + virtual void setMaxDuration(double duration); + + /** @brief Get the tracing category associated to the current action */ + char* getCategory() const { return category_; } + /** @brief Set the tracing category of the current Action */ + void setCategory(const char* 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 state set in which the action is */ + ActionList* getStateSet() const { return stateSet_; }; + + simgrid::surf::Model* getModel() const { return model_; } + +protected: + ActionList* stateSet_; + int refcount_ = 1; + +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 */ + + double cost_; + simgrid::surf::Model* model_; + void* data_ = nullptr; /**< for your convenience */ + + /* LMM */ + double lastUpdate_ = 0; + double lastValue_ = 0; + kernel::lmm::Variable* variable_ = nullptr; + Action::Type type_ = Action::Type::NOTSET; + boost::optional heapHandle_ = boost::none; + +public: + virtual void updateRemainingLazy(double now) { THROW_IMPOSSIBLE; }; + 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() { lastUpdate_ = surf_get_clock(); } + 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; +}; + +typedef Action::ActionList ActionList; +typedef Action::ActionLmmList ActionLmmList; +typedef Action::ActionLmmList* ActionLmmListPtr; +} // namespace surf +} // namespace simgrid +#endif diff --git a/src/kernel/resource/Model.cpp b/src/kernel/resource/Model.cpp new file mode 100644 index 0000000000..ac5f5ecf29 --- /dev/null +++ b/src/kernel/resource/Model.cpp @@ -0,0 +1,167 @@ +/* Copyright (c) 2004-2018. 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. */ + +#include "src/kernel/resource/Model.hpp" +#include "src/kernel/lmm/maxmin.hpp" + +XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(resource); + +namespace simgrid { +namespace surf { + +Model::Model() : maxminSystem_(nullptr) +{ + readyActionSet_ = new ActionList(); + runningActionSet_ = new ActionList(); + failedActionSet_ = new ActionList(); + doneActionSet_ = new ActionList(); + + modifiedSet_ = nullptr; + updateMechanism_ = UM_UNDEFINED; + selectiveUpdate_ = 0; +} + +Model::~Model() +{ + delete readyActionSet_; + delete runningActionSet_; + delete failedActionSet_; + delete doneActionSet_; + delete modifiedSet_; + delete maxminSystem_; +} + +Action* Model::actionHeapPop() +{ + Action* action = actionHeap_.top().second; + actionHeap_.pop(); + action->clearHeapHandle(); + return action; +} + +double Model::nextOccuringEvent(double now) +{ + // FIXME: set the good function once and for all + if (updateMechanism_ == UM_LAZY) + return nextOccuringEventLazy(now); + else if (updateMechanism_ == UM_FULL) + return nextOccuringEventFull(now); + else + xbt_die("Invalid cpu update mechanism!"); +} + +double Model::nextOccuringEventLazy(double now) +{ + XBT_DEBUG("Before share resources, the size of modified actions set is %zu", modifiedSet_->size()); + lmm_solve(maxminSystem_); + XBT_DEBUG("After share resources, The size of modified actions set is %zu", modifiedSet_->size()); + + while (not modifiedSet_->empty()) { + Action* action = &(modifiedSet_->front()); + modifiedSet_->pop_front(); + bool max_dur_flag = false; + + if (action->getStateSet() != runningActionSet_) + continue; + + /* bogus priority, skip it */ + if (action->getPriority() <= 0 || action->getType() == Action::Type::LATENCY) + continue; + + action->updateRemainingLazy(now); + + double min = -1; + double share = action->getVariable()->get_value(); + + if (share > 0) { + double time_to_completion; + if (action->getRemains() > 0) { + time_to_completion = action->getRemainsNoUpdate() / share; + } else { + time_to_completion = 0.0; + } + min = now + time_to_completion; // when the task will complete if nothing changes + } + + if ((action->getMaxDuration() > NO_MAX_DURATION) && + (min <= -1 || action->getStartTime() + action->getMaxDuration() < min)) { + // when the task will complete anyway because of the deadline if any + min = action->getStartTime() + action->getMaxDuration(); + max_dur_flag = true; + } + + XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int); + + XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action, + action->getStartTime(), min, share, action->getMaxDuration()); + + if (min > -1) { + action->heapUpdate(actionHeap_, min, max_dur_flag ? Action::Type::MAX_DURATION : Action::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 actionHeapIsEmpty()) { + double min = actionHeapTopDate() - now; + XBT_DEBUG("minimum with the HEAP %f", min); + return min; + } else { + XBT_DEBUG("The HEAP is empty, thus returning -1"); + return -1; + } +} + +double Model::nextOccuringEventFull(double /*now*/) +{ + maxminSystem_->solve_fun(maxminSystem_); + + double min = -1; + + for (Action& action : *getRunningActionSet()) { + double value = action.getVariable()->get_value(); + if (value > 0) { + if (action.getRemains() > 0) + value = action.getRemainsNoUpdate() / value; + else + value = 0.0; + if (min < 0 || value < min) { + min = value; + XBT_DEBUG("Updating min (value) with %p: %f", &action, min); + } + } + if ((action.getMaxDuration() >= 0) && (min < 0 || action.getMaxDuration() < min)) { + min = action.getMaxDuration(); + XBT_DEBUG("Updating min (duration) with %p: %f", &action, min); + } + } + XBT_DEBUG("min value : %f", min); + + return min; +} + +void Model::updateActionsState(double now, double delta) +{ + if (updateMechanism_ == UM_FULL) + updateActionsStateFull(now, delta); + else if (updateMechanism_ == UM_LAZY) + updateActionsStateLazy(now, delta); + else + xbt_die("Invalid cpu update mechanism!"); +} + +void Model::updateActionsStateLazy(double /*now*/, double /*delta*/) +{ + THROW_UNIMPLEMENTED; +} + +void Model::updateActionsStateFull(double /*now*/, double /*delta*/) +{ + THROW_UNIMPLEMENTED; +} + +} // namespace surf +} // namespace simgrid diff --git a/src/kernel/resource/Model.hpp b/src/kernel/resource/Model.hpp new file mode 100644 index 0000000000..704febba06 --- /dev/null +++ b/src/kernel/resource/Model.hpp @@ -0,0 +1,100 @@ +/* Copyright (c) 2004-2018. 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. */ + +#ifndef SIMGRID_KERNEL_RESOURCE_MODEL_HPP +#define SIMGRID_KERNEL_RESOURCE_MODEL_HPP + +#include "src/kernel/resource/Action.hpp" + +namespace simgrid { +namespace surf { + +/** @ingroup SURF_interface + * @brief SURF model interface class + * @details A model is an object which handle the interactions between its Resources and its Actions + */ +XBT_PUBLIC_CLASS Model +{ +public: + Model(); + virtual ~Model(); + + /** @brief Get the set of [actions](@ref Action) in *ready* state */ + virtual ActionList* getReadyActionSet() const { return readyActionSet_; } + + /** @brief Get the set of [actions](@ref Action) in *running* state */ + virtual ActionList* getRunningActionSet() const { return runningActionSet_; } + + /** @brief Get the set of [actions](@ref Action) in *failed* state */ + virtual ActionList* getFailedActionSet() const { return failedActionSet_; } + + /** @brief Get the set of [actions](@ref Action) in *done* state */ + virtual ActionList* getDoneActionSet() const { return doneActionSet_; } + + /** @brief Get the set of modified [actions](@ref Action) */ + virtual ActionLmmListPtr getModifiedSet() const { return modifiedSet_; } + + /** @brief Get the maxmin system of the current Model */ + lmm_system_t getMaxminSystem() const { return maxminSystem_; } + + /** + * @brief Get the update mechanism of the current Model + * @see e_UM_t + */ + e_UM_t getUpdateMechanism() const { return updateMechanism_; } + void setUpdateMechanism(e_UM_t mechanism) { updateMechanism_ = mechanism; } + + /** @brief Get Action heap */ + heap_type& getActionHeap() { return actionHeap_; } + + double actionHeapTopDate() const { return actionHeap_.top().first; } + Action* actionHeapPop(); + bool actionHeapIsEmpty() const { return actionHeap_.empty(); } + + /** + * @brief Share the resources between the actions + * + * @param now The current time of the simulation + * @return The delta of time till the next action will finish + */ + virtual double nextOccuringEvent(double now); + virtual double nextOccuringEventLazy(double now); + virtual double nextOccuringEventFull(double now); + + /** + * @brief Update action to the current time + * + * @param now The current time of the simulation + * @param delta The delta of time since the last update + */ + virtual void updateActionsState(double now, double delta); + virtual void updateActionsStateLazy(double now, double delta); + virtual void updateActionsStateFull(double now, double delta); + + /** @brief Returns whether this model have an idempotent shareResource() + * + * The only model that is not is NS3: computing the next timestamp moves the model up to that point, + * so we need to call it only when the next timestamp of other sources is computed. + */ + virtual bool nextOccuringEventIsIdempotent() { return true; } + +protected: + ActionLmmListPtr modifiedSet_; + lmm_system_t maxminSystem_ = nullptr; + bool selectiveUpdate_; + +private: + e_UM_t updateMechanism_ = UM_UNDEFINED; + ActionList* readyActionSet_; /**< Actions in state SURF_ACTION_READY */ + ActionList* runningActionSet_; /**< Actions in state SURF_ACTION_RUNNING */ + ActionList* failedActionSet_; /**< Actions in state SURF_ACTION_FAILED */ + ActionList* doneActionSet_; /**< Actions in state SURF_ACTION_DONE */ + heap_type actionHeap_; +}; + +} // namespace surf +} // namespace simgrid + +#endif diff --git a/src/kernel/resource/Resource.hpp b/src/kernel/resource/Resource.hpp index 96a56af6d3..80481fbf24 100644 --- a/src/kernel/resource/Resource.hpp +++ b/src/kernel/resource/Resource.hpp @@ -3,8 +3,8 @@ /* 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. */ -#ifndef SIMGRID_KERNEL_MODEL_RESOURCE_HPP -#define SIMGRID_KERNEL_MODEL_RESOURCE_HPP +#ifndef SIMGRID_KERNEL_RESOURCE_RESOURCE_HPP +#define SIMGRID_KERNEL_RESOURCE_RESOURCE_HPP #include "src/surf/surf_interface.hpp" diff --git a/src/simdag/sd_global.cpp b/src/simdag/sd_global.cpp index 44767bcff1..f6eeabc500 100644 --- a/src/simdag/sd_global.cpp +++ b/src/simdag/sd_global.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2017. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2018. 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. */ @@ -7,6 +7,7 @@ #include "simgrid/s4u/Engine.hpp" #include "simgrid/sg_config.h" #include "src/include/instr/instr_interface.h" +#include "src/kernel/resource/Action.hpp" #include "src/surf/surf_interface.hpp" XBT_LOG_NEW_CATEGORY(sd, "Logging specific to SimDag"); diff --git a/src/surf/StorageImpl.hpp b/src/surf/StorageImpl.hpp index c3b1d0f3ec..a77c79b3c3 100644 --- a/src/surf/StorageImpl.hpp +++ b/src/surf/StorageImpl.hpp @@ -8,6 +8,8 @@ #include #include "simgrid/s4u/Storage.hpp" +#include "src/kernel/resource/Action.hpp" +#include "src/kernel/resource/Model.hpp" #include "src/kernel/resource/Resource.hpp" #include "src/surf/PropertyHolder.hpp" #include "surf_interface.hpp" diff --git a/src/surf/cpu_interface.hpp b/src/surf/cpu_interface.hpp index 1082ea2fc3..42e1a48dad 100644 --- a/src/surf/cpu_interface.hpp +++ b/src/surf/cpu_interface.hpp @@ -8,6 +8,7 @@ #include "simgrid/s4u/Host.hpp" #include "src/kernel/lmm/maxmin.hpp" +#include "src/kernel/resource/Model.hpp" #include "src/kernel/resource/Resource.hpp" #include diff --git a/src/surf/network_interface.hpp b/src/surf/network_interface.hpp index 681706d9e2..0dd7dacfeb 100644 --- a/src/surf/network_interface.hpp +++ b/src/surf/network_interface.hpp @@ -8,6 +8,7 @@ #include "simgrid/s4u/Link.hpp" #include "src/kernel/lmm/maxmin.hpp" +#include "src/kernel/resource/Model.hpp" #include "src/kernel/resource/Resource.hpp" #include "src/surf/PropertyHolder.hpp" #include "src/surf/surf_interface.hpp" diff --git a/src/surf/surf_interface.cpp b/src/surf/surf_interface.cpp index f5a6a348bb..222720f6c5 100644 --- a/src/surf/surf_interface.cpp +++ b/src/surf/surf_interface.cpp @@ -348,388 +348,3 @@ void surf_exit() NOW = 0; /* Just in case the user plans to restart the simulation afterward */ } - -/********* - * Model * - *********/ - -namespace simgrid { -namespace surf { - -Model::Model() - : maxminSystem_(nullptr) -{ - readyActionSet_ = new ActionList(); - runningActionSet_ = new ActionList(); - failedActionSet_ = new ActionList(); - doneActionSet_ = new ActionList(); - - modifiedSet_ = nullptr; - updateMechanism_ = UM_UNDEFINED; - selectiveUpdate_ = 0; -} - -Model::~Model(){ - delete readyActionSet_; - delete runningActionSet_; - delete failedActionSet_; - delete doneActionSet_; - delete modifiedSet_; - delete maxminSystem_; -} - -Action* Model::actionHeapPop() -{ - Action* action = actionHeap_.top().second; - actionHeap_.pop(); - action->clearHeapHandle(); - return action; -} - -double Model::nextOccuringEvent(double now) -{ - //FIXME: set the good function once and for all - if (updateMechanism_ == UM_LAZY) - return nextOccuringEventLazy(now); - else if (updateMechanism_ == UM_FULL) - return nextOccuringEventFull(now); - else - xbt_die("Invalid cpu update mechanism!"); -} - -double Model::nextOccuringEventLazy(double now) -{ - XBT_DEBUG("Before share resources, the size of modified actions set is %zu", modifiedSet_->size()); - lmm_solve(maxminSystem_); - XBT_DEBUG("After share resources, The size of modified actions set is %zu", modifiedSet_->size()); - - while (not modifiedSet_->empty()) { - Action *action = &(modifiedSet_->front()); - modifiedSet_->pop_front(); - bool max_dur_flag = false; - - if (action->getStateSet() != runningActionSet_) - continue; - - /* bogus priority, skip it */ - if (action->getPriority() <= 0 || action->getType() == Action::Type::LATENCY) - continue; - - action->updateRemainingLazy(now); - - double min = -1; - double share = action->getVariable()->get_value(); - - if (share > 0) { - double time_to_completion; - if (action->getRemains() > 0) { - time_to_completion = action->getRemainsNoUpdate() / share; - } else { - time_to_completion = 0.0; - } - min = now + time_to_completion; // when the task will complete if nothing changes - } - - if ((action->getMaxDuration() > NO_MAX_DURATION) && - (min <= -1 || action->getStartTime() + action->getMaxDuration() < min)) { - // when the task will complete anyway because of the deadline if any - min = action->getStartTime() + action->getMaxDuration(); - max_dur_flag = true; - } - - XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int); - - XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action, - action->getStartTime(), min, share, - action->getMaxDuration()); - - if (min > -1) { - action->heapUpdate(actionHeap_, min, max_dur_flag ? Action::Type::MAX_DURATION : Action::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 actionHeapIsEmpty()) { - double min = actionHeapTopDate() - now; - XBT_DEBUG("minimum with the HEAP %f", min); - return min; - } else { - XBT_DEBUG("The HEAP is empty, thus returning -1"); - return -1; - } -} - -double Model::nextOccuringEventFull(double /*now*/) { - maxminSystem_->solve_fun(maxminSystem_); - - double min = -1; - - for (Action& action : *getRunningActionSet()) { - double value = action.getVariable()->get_value(); - if (value > 0) { - if (action.getRemains() > 0) - value = action.getRemainsNoUpdate() / value; - else - value = 0.0; - if (min < 0 || value < min) { - min = value; - XBT_DEBUG("Updating min (value) with %p: %f", &action, min); - } - } - if ((action.getMaxDuration() >= 0) && (min < 0 || action.getMaxDuration() < min)) { - min = action.getMaxDuration(); - XBT_DEBUG("Updating min (duration) with %p: %f", &action, min); - } - } - XBT_DEBUG("min value : %f", min); - - return min; -} - -void Model::updateActionsState(double now, double delta) -{ - if (updateMechanism_ == UM_FULL) - updateActionsStateFull(now, delta); - else if (updateMechanism_ == UM_LAZY) - updateActionsStateLazy(now, delta); - else - xbt_die("Invalid cpu update mechanism!"); -} - -void Model::updateActionsStateLazy(double /*now*/, double /*delta*/) -{ - THROW_UNIMPLEMENTED; -} - -void Model::updateActionsStateFull(double /*now*/, double /*delta*/) -{ - THROW_UNIMPLEMENTED; -} - -} -} - -/************ - * Resource * - ************/ - -/********** - * Action * - **********/ - -namespace simgrid { -namespace surf { - -Action::Action(simgrid::surf::Model* model, double cost, bool failed) : Action(model, cost, failed, nullptr) -{ -} - -Action::Action(simgrid::surf::Model* model, double cost, bool failed, kernel::lmm::Variable* var) - : remains_(cost), start_(surf_get_clock()), cost_(cost), model_(model), variable_(var) -{ - if (failed) - stateSet_ = getModel()->getFailedActionSet(); - else - stateSet_ = getModel()->getRunningActionSet(); - - stateSet_->push_back(*this); -} - -Action::~Action() { - xbt_free(category_); -} - -void Action::finish(Action::State state) -{ - finishTime_ = surf_get_clock(); - setState(state); -} - -Action::State Action::getState() const -{ - if (stateSet_ == model_->getReadyActionSet()) - return Action::State::ready; - if (stateSet_ == model_->getRunningActionSet()) - return Action::State::running; - if (stateSet_ == model_->getFailedActionSet()) - return Action::State::failed; - if (stateSet_ == model_->getDoneActionSet()) - return Action::State::done; - return Action::State::not_in_the_system; -} - -void Action::setState(Action::State state) -{ - simgrid::xbt::intrusive_erase(*stateSet_, *this); - switch (state) { - case Action::State::ready: - stateSet_ = model_->getReadyActionSet(); - break; - case Action::State::running: - stateSet_ = model_->getRunningActionSet(); - break; - case Action::State::failed: - stateSet_ = model_->getFailedActionSet(); - break; - case Action::State::done: - stateSet_ = model_->getDoneActionSet(); - break; - default: - stateSet_ = nullptr; - break; - } - if (stateSet_) - stateSet_->push_back(*this); -} - -double Action::getBound() const -{ - return variable_ ? variable_->get_bound() : 0; -} - -void Action::setBound(double bound) -{ - XBT_IN("(%p,%g)", this, bound); - if (variable_) - getModel()->getMaxminSystem()->update_variable_bound(variable_, bound); - - if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate() != surf_get_clock()) - heapRemove(getModel()->getActionHeap()); - XBT_OUT(); -} - -void Action::setCategory(const char *category) -{ - category_ = xbt_strdup(category); -} - -void Action::ref(){ - refcount_++; -} - -void Action::setMaxDuration(double duration) -{ - maxDuration_ = duration; - if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap - heapRemove(getModel()->getActionHeap()); -} - -void Action::setSharingWeight(double weight) -{ - XBT_IN("(%p,%g)", this, weight); - sharingWeight_ = weight; - getModel()->getMaxminSystem()->update_variable_weight(getVariable(), weight); - - if (getModel()->getUpdateMechanism() == UM_LAZY) - heapRemove(getModel()->getActionHeap()); - XBT_OUT(); -} - -void Action::cancel(){ - setState(Action::State::failed); - if (getModel()->getUpdateMechanism() == UM_LAZY) { - if (modifiedSetHook_.is_linked()) - simgrid::xbt::intrusive_erase(*getModel()->getModifiedSet(), *this); - heapRemove(getModel()->getActionHeap()); - } -} - -int Action::unref(){ - refcount_--; - if (not refcount_) { - if (stateSetHook_.is_linked()) - simgrid::xbt::intrusive_erase(*stateSet_, *this); - if (getVariable()) - getModel()->getMaxminSystem()->variable_free(getVariable()); - if (getModel()->getUpdateMechanism() == UM_LAZY) { - /* remove from heap */ - heapRemove(getModel()->getActionHeap()); - if (modifiedSetHook_.is_linked()) - simgrid::xbt::intrusive_erase(*getModel()->getModifiedSet(), *this); - } - delete this; - return 1; - } - return 0; -} - -void Action::suspend() -{ - XBT_IN("(%p)", this); - if (suspended_ != SuspendStates::sleeping) { - getModel()->getMaxminSystem()->update_variable_weight(getVariable(), 0.0); - if (getModel()->getUpdateMechanism() == UM_LAZY){ - heapRemove(getModel()->getActionHeap()); - if (getModel()->getUpdateMechanism() == UM_LAZY && stateSet_ == getModel()->getRunningActionSet() && - sharingWeight_ > 0) { - //If we have a lazy model, we need to update the remaining value accordingly - updateRemainingLazy(surf_get_clock()); - } - } - suspended_ = SuspendStates::suspended; - } - XBT_OUT(); -} - -void Action::resume() -{ - XBT_IN("(%p)", this); - if (suspended_ != SuspendStates::sleeping) { - getModel()->getMaxminSystem()->update_variable_weight(getVariable(), getPriority()); - suspended_ = SuspendStates::not_suspended; - if (getModel()->getUpdateMechanism() == UM_LAZY) - heapRemove(getModel()->getActionHeap()); - } - XBT_OUT(); -} - -bool Action::isSuspended() -{ - return suspended_ == SuspendStates::suspended; -} -/* insert action on heap using a given key and a hat (heap_action_type) - * a hat can be of three types for communications: - * - * NORMAL = this is a normal heap entry stating the date to finish transmitting - * LATENCY = 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 is reached - */ -void Action::heapInsert(heap_type& heap, double key, Action::Type hat) -{ - type_ = hat; - heapHandle_ = heap.emplace(std::make_pair(key, this)); -} - -void Action::heapRemove(heap_type& heap) -{ - type_ = Action::Type::NOTSET; - if (heapHandle_) { - heap.erase(*heapHandle_); - clearHeapHandle(); - } -} - -void Action::heapUpdate(heap_type& heap, double key, Action::Type hat) -{ - type_ = hat; - if (heapHandle_) { - heap.update(*heapHandle_, std::make_pair(key, this)); - } else { - heapHandle_ = heap.emplace(std::make_pair(key, this)); - } -} - -double Action::getRemains() -{ - XBT_IN("(%p)", this); - /* update remains before return it */ - if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */ - updateRemainingLazy(surf_get_clock()); - XBT_OUT(); - return remains_; -} - -} -} diff --git a/src/surf/surf_interface.hpp b/src/surf/surf_interface.hpp index e10c1e5934..b8e41a1d8a 100644 --- a/src/surf/surf_interface.hpp +++ b/src/surf/surf_interface.hpp @@ -82,298 +82,4 @@ int XBT_PRIVATE __surf_is_absolute_file_path(const char *file_path); */ XBT_PUBLIC_DATA(std::vector*) all_existing_models; -namespace simgrid { -namespace surf { - -typedef std::pair heap_element_type; -typedef boost::heap::pairing_heap, boost::heap::stable, - boost::heap::compare>> - heap_type; - -/** @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) - */ -XBT_PUBLIC_CLASS 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(); } - - typedef boost::intrusive::member_hook, &Action::modifiedSetHook_> - ActionLmmOptions; - typedef boost::intrusive::list ActionLmmList; - - boost::intrusive::list_member_hook<> stateSetHook_; - typedef boost::intrusive::member_hook, &Action::stateSetHook_> - ActionOptions; - typedef boost::intrusive::list ActionList; - - 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 ? */ - }; - - enum class SuspendStates { - not_suspended = 0, /**< Action currently not suspended **/ - suspended, - sleeping - }; - - enum class Type { LATENCY = 100, MAX_DURATION, NORMAL, NOTSET }; - - /** - * @brief Action constructor - * - * @param model The Model associated to this Action - * @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::surf::Model* model, double cost, bool failed); - - /** - * @brief Action constructor - * - * @param model The Model associated to this Action - * @param cost The cost of the Action - * @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::surf::Model * model, double cost, bool failed, kernel::lmm::Variable* var); - - virtual ~Action(); - - /** - * @brief Mark that the action is now finished - * - * @param state the new [state](\ref simgrid::surf::Action::State) of the current Action - */ - void finish(Action::State state); - - /** @brief Get the [state](\ref simgrid::surf::Action::State) of the current Action */ - Action::State getState() const; /**< get the state*/ - /** @brief Set the [state](\ref simgrid::surf::Action::State) of the current Action */ - virtual void setState(Action::State state); - - /** @brief Get the bound of the current Action */ - double getBound() const; - /** @brief Set the bound of the current Action */ - void setBound(double bound); - - /** @brief Get the start time of the current action */ - double getStartTime() const { return start_; } - /** @brief Get the finish time of the current action */ - double getFinishTime() const { return finishTime_; } - - /** @brief Get the user data associated to the current action */ - void* getData() const { return data_; } - /** @brief Set the user data associated to the current action */ - void setData(void* data) { data_ = data; } - - /** @brief Get the cost of the current action */ - double getCost() const { return cost_; } - /** @brief Set the cost of the current action */ - void setCost(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) {double_update(&maxDuration_, delta,sg_surf_precision);} - - /** @brief Update the remaining time of the current action - * @param delta Amount to remove from the remaining time */ - void updateRemains(double delta) {double_update(&remains_, delta, sg_maxmin_precision*sg_surf_precision);} - - /** @brief Set the remaining time of the current action */ - void setRemains(double value) {remains_ = value;} - /** @brief Get the remaining time of the current action after updating the resource */ - virtual double getRemains(); - /** @brief Get the remaining time of the current action without updating the resource */ - double getRemainsNoUpdate() const { return remains_; } - - /** @brief Set the finish time of the current action */ - void setFinishTime(double value) {finishTime_ = 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(); - - /** @brief Cancel the current Action if running */ - virtual void cancel(); - - /** @brief Suspend the current Action */ - virtual void suspend(); - - /** @brief Resume the current Action */ - virtual void resume(); - - /** @brief Returns true if the current action is running */ - virtual bool isSuspended(); - - /** @brief Get the maximum duration of the current action */ - double getMaxDuration() const { return maxDuration_; } - /** @brief Set the maximum duration of the current Action */ - virtual void setMaxDuration(double duration); - - /** @brief Get the tracing category associated to the current action */ - char* getCategory() const { return category_; } - /** @brief Set the tracing category of the current Action */ - void setCategory(const char *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 state set in which the action is */ - ActionList* getStateSet() const { return stateSet_; }; - - simgrid::surf::Model* getModel() const { return model_; } - -protected: - ActionList* stateSet_; - int refcount_ = 1; - -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 */ - - double cost_; - simgrid::surf::Model *model_; - void *data_ = nullptr; /**< for your convenience */ - - /* LMM */ - double lastUpdate_ = 0; - double lastValue_ = 0; - kernel::lmm::Variable* variable_ = nullptr; - Action::Type type_ = Action::Type::NOTSET; - boost::optional heapHandle_ = boost::none; - -public: - virtual void updateRemainingLazy(double now) { THROW_IMPOSSIBLE; }; - 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() {lastUpdate_ = surf_get_clock();} - 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; -}; - -typedef Action::ActionList ActionList; -typedef Action::ActionLmmList ActionLmmList; -typedef Action::ActionLmmList* ActionLmmListPtr; - -/********* - * Model * - *********/ - -/** @ingroup SURF_interface - * @brief SURF model interface class - * @details A model is an object which handle the interactions between its Resources and its Actions - */ -XBT_PUBLIC_CLASS Model { -public: - Model(); - virtual ~Model(); - - /** @brief Get the set of [actions](@ref Action) in *ready* state */ - virtual ActionList* getReadyActionSet() const { return readyActionSet_; } - - /** @brief Get the set of [actions](@ref Action) in *running* state */ - virtual ActionList* getRunningActionSet() const { return runningActionSet_; } - - /** @brief Get the set of [actions](@ref Action) in *failed* state */ - virtual ActionList* getFailedActionSet() const { return failedActionSet_; } - - /** @brief Get the set of [actions](@ref Action) in *done* state */ - virtual ActionList* getDoneActionSet() const { return doneActionSet_; } - - /** @brief Get the set of modified [actions](@ref Action) */ - virtual ActionLmmListPtr getModifiedSet() const { return modifiedSet_; } - - /** @brief Get the maxmin system of the current Model */ - lmm_system_t getMaxminSystem() const { return maxminSystem_; } - - /** - * @brief Get the update mechanism of the current Model - * @see e_UM_t - */ - e_UM_t getUpdateMechanism() const { return updateMechanism_; } - void setUpdateMechanism(e_UM_t mechanism) { updateMechanism_ = mechanism; } - - /** @brief Get Action heap */ - heap_type& getActionHeap() { return actionHeap_; } - - double actionHeapTopDate() const { return actionHeap_.top().first; } - Action* actionHeapPop(); - bool actionHeapIsEmpty() const { return actionHeap_.empty(); } - - /** - * @brief Share the resources between the actions - * - * @param now The current time of the simulation - * @return The delta of time till the next action will finish - */ - virtual double nextOccuringEvent(double now); - virtual double nextOccuringEventLazy(double now); - virtual double nextOccuringEventFull(double now); - - /** - * @brief Update action to the current time - * - * @param now The current time of the simulation - * @param delta The delta of time since the last update - */ - virtual void updateActionsState(double now, double delta); - virtual void updateActionsStateLazy(double now, double delta); - virtual void updateActionsStateFull(double now, double delta); - - /** @brief Returns whether this model have an idempotent shareResource() - * - * The only model that is not is NS3: computing the next timestamp moves the model up to that point, - * so we need to call it only when the next timestamp of other sources is computed. - */ - virtual bool nextOccuringEventIsIdempotent() { return true;} - -protected: - ActionLmmListPtr modifiedSet_; - lmm_system_t maxminSystem_ = nullptr; - bool selectiveUpdate_; - -private: - e_UM_t updateMechanism_ = UM_UNDEFINED; - ActionList* readyActionSet_; /**< Actions in state SURF_ACTION_READY */ - ActionList* runningActionSet_; /**< Actions in state SURF_ACTION_RUNNING */ - ActionList* failedActionSet_; /**< Actions in state SURF_ACTION_FAILED */ - ActionList* doneActionSet_; /**< Actions in state SURF_ACTION_DONE */ - heap_type actionHeap_; -}; - -} -} - -/************ - * Resource * - ************/ - - #endif /* SURF_MODEL_H_ */ diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index 895f918f29..4bee3f73dc 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -303,6 +303,10 @@ set(SURF_SRC src/kernel/lmm/maxmin.hpp src/kernel/lmm/maxmin.cpp + src/kernel/resource/Action.hpp + src/kernel/resource/Action.cpp + src/kernel/resource/Model.hpp + src/kernel/resource/Model.cpp src/kernel/resource/Resource.hpp src/kernel/resource/Resource.cpp