}
// Does half the job
-bool Api::request_depend_asymmetric(smx_simcall_t r1, smx_simcall_t r2) const
+bool Api::request_depend_asymmetric(smx_simcall_t r1, smx_simcall_t r2) const
{
if (r1->call_ == Simcall::COMM_ISEND && r2->call_ == Simcall::COMM_IRECV)
return false;
const kernel::activity::CommImpl* synchro2 = get_comm(r2);
if ((r1->call_ == Simcall::COMM_ISEND || r1->call_ == Simcall::COMM_IRECV) && r2->call_ == Simcall::COMM_WAIT) {
- auto mbox = get_mbox_remote_addr(r1);;
+ auto mbox = get_mbox_remote_addr(r1);
RemotePtr<kernel::activity::MailboxImpl> synchro2_mbox_cpy = remote(synchro2->mbox_cpy);
- if (mbox != synchro2_mbox_cpy
- && simcall_comm_wait__get__timeout(r2) <= 0)
+ if (mbox != synchro2_mbox_cpy && simcall_comm_wait__get__timeout(r2) <= 0)
return false;
if ((r1->issuer_ != synchro2->src_actor_.get()) && (r1->issuer_ != synchro2->dst_actor_.get()) &&
RemotePtr<kernel::activity::CommImpl> Api::get_comm_waitany_raw_addr(smx_simcall_t request, int value) const
{
- auto addr = simgrid::simix::unmarshal_raw<simgrid::kernel::activity::CommImpl**>(request->args_[0]) + value;
+ auto addr = simgrid::simix::unmarshal_raw<simgrid::kernel::activity::CommImpl**>(request->args_[0]) + value;
auto comm_addr = mc_model_checker->get_remote_simulation().read(remote(addr));
return RemotePtr<kernel::activity::CommImpl>(static_cast<kernel::activity::CommImpl*>(comm_addr));
}
case Simcall::COMM_ISEND:
case Simcall::COMM_IRECV: {
auto mbox_addr_ptr = simix::unmarshal<smx_mailbox_t>(req->args_[1]);
- mbox_addr = remote(mbox_addr_ptr);
+ mbox_addr = remote(mbox_addr_ptr);
break;
}
default:
return nullptr;
}
+std::list<udpor_transition_t> Api::get_enabled_transitions(simgrid::mc::State* state)
+{
+ std::list<udpor_transition_t> tr_list{};
+
+ for (auto& actor : mc_model_checker->get_remote_simulation().actors()) {
+ auto actor_pid = actor.copy.get_buffer()->get_pid();
+ auto actor_impl = actor.copy.get_buffer();
+
+ // Only consider the actors that were marked as interleaving by the checker algorithm
+ if (not state->actor_states_[actor_pid].is_todo())
+ continue;
+ // Not executable in the application
+ if (not simgrid::mc::actor_is_enabled(actor_impl))
+ continue;
+
+ udpor_transition_t udpor_transition = std::unique_ptr<s_udpor_transition>(new s_udpor_transition());
+ Simcall simcall_call = actor_impl->simcall_.call_;
+ smx_simcall_t simcall = &actor_impl->simcall_;
+ udpor_transition->call_ = simcall_call;
+ switch (simcall_call) {
+ case Simcall::COMM_ISEND:
+ case Simcall::COMM_IRECV: {
+ udpor_transition->mbox_remote_addr = get_mbox_remote_addr(simcall);
+ udpor_transition->comm_remote_addr = get_comm_remote_addr(simcall);
+ break;
+ }
+
+ default:
+ break;
+ }
+ tr_list.emplace_back(std::move(udpor_transition));
+ }
+
+ return tr_list;
+}
+
bool Api::simcall_check_dependency(smx_simcall_t const req1, smx_simcall_t const req2) const
{
if (req1->issuer_ == req2->issuer_)
return false;
- /* Wait with timeout transitions are not considered by the independence theorem, thus we consider them as dependent with all other transitions */
+ /* Wait with timeout transitions are not considered by the independence theorem, thus we consider them as dependent
+ * with all other transitions */
if ((req1->call_ == Simcall::COMM_WAIT && simcall_comm_wait__get__timeout(req1) > 0) ||
(req2->call_ == Simcall::COMM_WAIT && simcall_comm_wait__get__timeout(req2) > 0))
return true;
#include "simgrid/forward.h"
#include "src/mc/mc_forward.hpp"
+#include "src/mc/mc_record.hpp"
#include "src/mc/mc_request.hpp"
#include "src/mc/mc_state.hpp"
-#include "src/mc/mc_record.hpp"
#include "xbt/automaton.hpp"
#include "xbt/base.h"
namespace simgrid {
namespace mc {
+/**
+ * @brief Maintains the transition's information.
+ */
+struct s_udpor_transition {
+ simgrid::simix::Simcall call_ = simgrid::simix::Simcall::NONE;
+ long issuer_id = -1;
+ RemotePtr<kernel::activity::MailboxImpl> mbox_remote_addr {}; // used to represent mailbox remote address for isend and ireceive transitions
+ RemotePtr<kernel::activity::ActivityImpl> comm_remote_addr {}; // the communication this transition concerns (to be used only for isend, ireceive, wait and test)
+};
+
+typedef std::unique_ptr<s_udpor_transition> udpor_transition_t;
+
/*
** This class aimes to implement FACADE APIs for simgrid. The FACADE layer sits between the CheckerSide
** (Unfolding_Checker, DPOR, ...) layer and the
}
};
-simgrid::kernel::activity::CommImpl* get_comm(smx_simcall_t const r) const;
-bool request_depend_asymmetric(smx_simcall_t r1, smx_simcall_t r2) const;
+ simgrid::kernel::activity::CommImpl* get_comm(smx_simcall_t const r) const;
+ bool request_depend_asymmetric(smx_simcall_t r1, smx_simcall_t r2) const;
public:
// No copy:
void initialize(char** argv) const;
- // ACTOR APIs
+ // ACTOR APIs
std::vector<simgrid::mc::ActorInformation>& get_actors() const;
bool actor_is_enabled(aid_t pid) const;
unsigned long get_maxpid() const;
void dump_record_path() const;
smx_simcall_t mc_state_choose_request(simgrid::mc::State* state) const;
+ // UDPOR APIs
+ std::list<udpor_transition_t> get_enabled_transitions(simgrid::mc::State* state);
+
// SIMCALL APIs
std::string request_to_string(smx_simcall_t req, int value, RequestType request_type) const;
std::string request_get_dot_output(smx_simcall_t req, int value) const;
- const char *simcall_get_name(simgrid::simix::Simcall kind) const;
+ const char* simcall_get_name(simgrid::simix::Simcall kind) const;
smx_actor_t simcall_get_issuer(s_smx_simcall const* req) const;
long simcall_get_actor_id(s_smx_simcall const* req) const;
RemotePtr<kernel::activity::MailboxImpl> get_mbox_remote_addr(smx_simcall_t const req) const;
void s_close() const;
void execute(Transition const& transition) const;
- // AUTOMATION APIs
- #if SIMGRID_HAVE_MC
- void automaton_load(const char *file) const;
- #endif
+// AUTOMATION APIs
+#if SIMGRID_HAVE_MC
+ void automaton_load(const char* file) const;
+#endif
std::vector<int> automaton_propositional_symbol_evaluate() const;
std::vector<xbt_automaton_state_t> get_automaton_state() const;
int compare_automaton_exp_label(const xbt_automaton_exp_label* l) const;
void set_property_automaton(xbt_automaton_state_t const& automaton_state) const;
- inline DerefAndCompareByActorsCountAndUsedHeap compare_pair() const {
+ inline DerefAndCompareByActorsCountAndUsedHeap compare_pair() const
+ {
return DerefAndCompareByActorsCountAndUsedHeap();
}
- inline int automaton_state_compare(const_xbt_automaton_state_t const& s1, const_xbt_automaton_state_t const& s2) const {
+ inline int automaton_state_compare(const_xbt_automaton_state_t const& s1, const_xbt_automaton_state_t const& s2) const
+ {
return xbt_automaton_state_compare(s1, s2);
}
xbt_automaton_exp_label_t get_automaton_transition_label(xbt_dynar_t const& dynar, int index) const;
xbt_automaton_state_t get_automaton_transition_dst(xbt_dynar_t const& dynar, int index) const;
// DYNAR APIs
- inline unsigned long get_dynar_length(const_xbt_dynar_t const& dynar) const {
- return xbt_dynar_length(dynar);
- }
+ inline unsigned long get_dynar_length(const_xbt_dynar_t const& dynar) const { return xbt_dynar_length(dynar); }
};
} // namespace mc