X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/d8303a57360023593881a8c45c37709b4941f431..500f2123a1cc27f0727a1da2f7f9917e36f63ad5:/src/mc/api/ActorState.hpp diff --git a/src/mc/api/ActorState.hpp b/src/mc/api/ActorState.hpp index 79cbe420ef..d407e5b893 100644 --- a/src/mc/api/ActorState.hpp +++ b/src/mc/api/ActorState.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. 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. */ @@ -9,16 +9,55 @@ #include "src/kernel/activity/CommImpl.hpp" #include "src/mc/remote/RemotePtr.hpp" +#include +#include + namespace simgrid::mc { /* On every state, each actor has an entry of the following type. - * This represents both the actor and its transition because - * an actor cannot have more than one enabled transition at a given time. + * This usually represents both the actor and its transition because + * most of the time an actor cannot have more than one enabled transition + * at a given time. However, certain transitions have multiple "paths" + * that can be followed, which means that a given actor may be able + * to do more than one thing at a time. + * + * Formally, at this state multiple transitions would exist all of + * which happened to be executed by the same actor. This distinction + * is important in cases */ class ActorState { + /** + * @brief The transitions that the actor is allowed to execute from this + * state, viz. those that are enabled for this actor + * + * Most actors can take only a single action from any given state. + * However, when an actor executes a transition with multiple + * possible variations (e.g. an MC_Random() [see class: RandomTransition] + * for more details]), multiple enabled actions are defined + * + * @invariant The transitions are arranged such that an actor + * with multiple possible paths of execution will contain all + * such transitions such that `pending_transitions_[i]` represents + * the variation of the transition with `times_considered = i`. + * + * @note: If only a subset of transitions of an actor that can + * take multiple transitions in some state are truly enabled, + * we would instead need to map `times_considered` to a transition, + * as the map is currently implicit in the ordering of the transitions + * in the vector + * + * TODO: If a single transition is taken at a time in a concurrent system, + * then nearly all of the transitions from in a state `s'` after taking + * an action `t` from state `s` (i.e. s -- t --> s') are the same + * sans for the new transition of the actor which just executed t. + * This means there may be a way to store the list once and apply differences + * rather than repeating elements frequently. + */ + std::vector> pending_transitions_; /* Possible exploration status of an actor transition in a state. - * Either the checker did not consider the transition, or it was considered and still to do, or considered and done. + * Either the checker did not consider the transition, or it was considered and still to do, or considered and + * done. */ enum class InterleavingType { /** This actor transition is not considered by the checker (yet?) */ @@ -45,15 +84,17 @@ class ActorState { bool enabled_; public: - ActorState(aid_t aid, bool enabled, unsigned int max_consider) - : aid_(aid), max_consider_(max_consider), enabled_(enabled) + ActorState(aid_t aid, bool enabled, unsigned int max_consider) : ActorState(aid, enabled, max_consider, {}) {} + + ActorState(aid_t aid, bool enabled, unsigned int max_consider, std::vector> transitions) + : pending_transitions_(std::move(transitions)), aid_(aid), max_consider_(max_consider), enabled_(enabled) { } unsigned int do_consider() { if (max_consider_ <= times_considered_ + 1) - set_done(); + mark_done(); return times_considered_++; } unsigned int get_times_considered() const { return times_considered_; } @@ -71,7 +112,30 @@ public: this->state_ = InterleavingType::todo; this->times_considered_ = 0; } - void set_done() { this->state_ = InterleavingType::done; } + void mark_done() { this->state_ = InterleavingType::done; } + + inline Transition* get_transition(unsigned times_considered) const + { + xbt_assert(times_considered < this->pending_transitions_.size(), + "Actor %ld does not have a state available transition with `times_considered = %u`,\n" + "yet one was asked for", + aid_, times_considered); + return this->pending_transitions_[times_considered].get(); + } + + inline void set_transition(std::unique_ptr t, unsigned times_considered) + { + xbt_assert(times_considered < this->pending_transitions_.size(), + "Actor %ld does not have a state available transition with `times_considered = %u`, " + "yet one was attempted to be set", + aid_, times_considered); + this->pending_transitions_[times_considered] = std::move(t); + } + + const std::vector>& get_enabled_transitions() const + { + return this->pending_transitions_; + }; }; } // namespace simgrid::mc