*/
class ModelChecker {
CheckerSide checker_side_;
- // This is the parent snapshot of the current state:
- PageStore page_store_{500};
std::unique_ptr<RemoteProcess> remote_process_;
Exploration* exploration_ = nullptr;
RemoteProcess& get_remote_process() { return *remote_process_; }
Channel& channel() { return checker_side_.get_channel(); }
- PageStore& page_store() { return page_store_; }
void start();
void shutdown();
namespace simgrid::mc {
/** @brief Save the current state */
-VisitedState::VisitedState(unsigned long state_number, unsigned int actor_count, std::size_t heap_bytes_used)
- : heap_bytes_used_(heap_bytes_used), actor_count_(actor_count), num_(state_number)
+VisitedState::VisitedState(unsigned long state_number, unsigned int actor_count, RemoteApp& remote_app)
+ : heap_bytes_used_(remote_app.get_remote_process().get_remote_heap_bytes())
+ , actor_count_(actor_count)
+ , num_(state_number)
{
- this->system_state_ = std::make_shared<simgrid::mc::Snapshot>(state_number);
+ this->system_state_ = std::make_shared<simgrid::mc::Snapshot>(state_number, remote_app.get_page_store());
}
void VisitedStates::prune()
/** @brief Checks whether a given state has already been visited by the algorithm. */
std::unique_ptr<simgrid::mc::VisitedState>
-VisitedStates::addVisitedState(unsigned long state_number, simgrid::mc::State* graph_state, std::size_t heap_bytes_used)
+VisitedStates::addVisitedState(unsigned long state_number, simgrid::mc::State* graph_state, RemoteApp& remote_app)
{
auto new_state =
- std::make_unique<simgrid::mc::VisitedState>(state_number, graph_state->get_actor_count(), heap_bytes_used);
+ std::make_unique<simgrid::mc::VisitedState>(state_number, graph_state->get_actor_count(), remote_app);
graph_state->set_system_state(new_state->system_state_);
XBT_DEBUG("Snapshot %p of visited state %ld (exploration stack state %ld)", new_state->system_state_.get(),
long num_; // unique id of that state in the storage of all stored IDs
long original_num_ = -1; // num field of the VisitedState to which I was declared equal to (used for dot_output)
- explicit VisitedState(unsigned long state_number, unsigned int actor_count, std::size_t heap_bytes_used);
+ explicit VisitedState(unsigned long state_number, unsigned int actor_count, RemoteApp& remote_app);
};
class XBT_PRIVATE VisitedStates {
std::vector<std::unique_ptr<simgrid::mc::VisitedState>> states_;
public:
void clear() { states_.clear(); }
- std::unique_ptr<simgrid::mc::VisitedState>
- addVisitedState(unsigned long state_number, simgrid::mc::State* graph_state, std::size_t heap_bytes_used);
+ std::unique_ptr<simgrid::mc::VisitedState> addVisitedState(unsigned long state_number,
+ simgrid::mc::State* graph_state, RemoteApp& remote_app);
private:
void prune();
/* Take the initial snapshot */
model_checker_->wait_for_requests();
- initial_snapshot_ = std::make_shared<simgrid::mc::Snapshot>(0);
+ initial_snapshot_ = std::make_shared<simgrid::mc::Snapshot>(0, page_store_);
}
RemoteApp::~RemoteApp()
class XBT_PUBLIC RemoteApp {
private:
std::unique_ptr<ModelChecker> model_checker_;
+ PageStore page_store_{500};
std::shared_ptr<simgrid::mc::Snapshot> initial_snapshot_;
// No copy:
/* Get the remote process */
RemoteProcess& get_remote_process() { return model_checker_->get_remote_process(); }
+
+ PageStore& get_page_store() { return page_store_; }
};
} // namespace simgrid::mc
long State::expended_states_ = 0;
-State::State(const RemoteApp& remote_app) : num_(++expended_states_)
+State::State(RemoteApp& remote_app) : num_(++expended_states_)
{
remote_app.get_actors_status(actors_to_run_);
/* Stateful model checking */
- if ((_sg_mc_checkpoint > 0 && (num_ % _sg_mc_checkpoint == 0)) || _sg_mc_termination) {
- system_state_ = std::make_shared<simgrid::mc::Snapshot>(num_);
- }
+ if ((_sg_mc_checkpoint > 0 && (num_ % _sg_mc_checkpoint == 0)) || _sg_mc_termination)
+ system_state_ = std::make_shared<simgrid::mc::Snapshot>(num_, remote_app.get_page_store());
}
-State::State(const RemoteApp& remote_app, const State* previous_state)
+State::State(RemoteApp& remote_app, const State* previous_state)
: default_transition_(std::make_unique<Transition>()), num_(++expended_states_)
{
/* Stateful model checking */
if ((_sg_mc_checkpoint > 0 && (num_ % _sg_mc_checkpoint == 0)) || _sg_mc_termination) {
- system_state_ = std::make_shared<simgrid::mc::Snapshot>(num_);
+ system_state_ = std::make_shared<simgrid::mc::Snapshot>(num_, remote_app.get_page_store());
}
/* For each actor in the previous sleep set, keep it if it is not dependent with current transition.
std::map<aid_t, Transition> sleep_set_;
public:
- explicit State(const RemoteApp& remote_app);
- explicit State(const RemoteApp& remote_app, const State* previous_state);
+ explicit State(RemoteApp& remote_app);
+ explicit State(RemoteApp& remote_app, const State* previous_state);
/* Returns a positive number if there is another transition to pick, or -1 if not */
aid_t next_transition() const;
/* Check whether we already explored next_state in the past (but only if interested in state-equality reduction) */
if (_sg_mc_max_visited_states > 0)
- visited_state_ = visited_states_.addVisitedState(next_state->get_num(), next_state.get(),
- get_remote_app().get_remote_process().get_remote_heap_bytes());
+ visited_state_ = visited_states_.addVisitedState(next_state->get_num(), next_state.get(), get_remote_app());
/* If this is a new state (or if we don't care about state-equality reduction) */
if (visited_state_ == nullptr) {
namespace simgrid::mc {
VisitedPair::VisitedPair(int pair_num, xbt_automaton_state_t prop_state,
- std::shared_ptr<const std::vector<int>> atomic_propositions, std::shared_ptr<State> app_state)
+ std::shared_ptr<const std::vector<int>> atomic_propositions, std::shared_ptr<State> app_state,
+ RemoteApp& remote_app)
: num(pair_num), prop_state_(prop_state)
{
this->app_state_ = std::move(app_state);
if (not this->app_state_->get_system_state())
- this->app_state_->set_system_state(std::make_shared<Snapshot>(pair_num));
+ this->app_state_->set_system_state(std::make_shared<Snapshot>(pair_num, remote_app.get_page_store()));
this->heap_bytes_used = mc_model_checker->get_remote_process().get_remote_heap_bytes();
this->actor_count_ = app_state_->get_actor_count();
this->other_num = -1;
std::shared_ptr<VisitedPair> LivenessChecker::insert_acceptance_pair(simgrid::mc::Pair* pair)
{
- auto new_pair =
- std::make_shared<VisitedPair>(pair->num, pair->prop_state_, pair->atomic_propositions, pair->app_state_);
+ auto new_pair = std::make_shared<VisitedPair>(pair->num, pair->prop_state_, pair->atomic_propositions,
+ pair->app_state_, get_remote_app());
auto [res_begin,
res_end] = boost::range::equal_range(acceptance_pairs_, new_pair.get(), [](auto const& a, auto const& b) {
return -1;
if (visited_pair == nullptr)
- visited_pair =
- std::make_shared<VisitedPair>(pair->num, pair->prop_state_, pair->atomic_propositions, pair->app_state_);
+ visited_pair = std::make_shared<VisitedPair>(pair->num, pair->prop_state_, pair->atomic_propositions,
+ pair->app_state_, get_remote_app());
auto [range_begin,
range_end] = boost::range::equal_range(visited_pairs_, visited_pair.get(), [](auto const& a, auto const& b) {
int actor_count_;
VisitedPair(int pair_num, xbt_automaton_state_t prop_state,
- std::shared_ptr<const std::vector<int>> atomic_propositions, std::shared_ptr<State> app_state);
+ std::shared_ptr<const std::vector<int>> atomic_propositions, std::shared_ptr<State> app_state,
+ RemoteApp& remote_app);
};
class XBT_PRIVATE LivenessChecker : public Exploration {
namespace simgrid::mc {
-Region::Region(RegionType region_type, void* start_addr, size_t size)
+Region::Region(PageStore& store, RegionType region_type, void* start_addr, size_t size)
: region_type_(region_type), start_addr_(start_addr), size_(size)
{
xbt_assert((((uintptr_t)start_addr) & (xbt_pagesize - 1)) == 0, "Start address not at the beginning of a page");
- chunks_ = ChunkedData(mc_model_checker->page_store(), mc_model_checker->get_remote_process(),
- RemotePtr<void>(start_addr), mmu::chunk_count(size));
+ chunks_ =
+ ChunkedData(store, mc_model_checker->get_remote_process(), RemotePtr<void>(start_addr), mmu::chunk_count(size));
}
/** @brief Restore a region from a snapshot
ChunkedData chunks_;
public:
- Region(RegionType type, void* start_addr, size_t size);
+ Region(PageStore& store, RegionType type, void* start_addr, size_t size);
Region(Region const&) = delete;
Region& operator=(Region const&) = delete;
Region(Region&& that) = delete;
get_remote_process()->write_bytes(ignored_data.data.data(), ignored_data.data.size(), remote(ignored_data.start));
}
-Snapshot::Snapshot(long num_state, RemoteProcess* process) : AddressSpace(process), num_state_(num_state)
+Snapshot::Snapshot(long num_state, PageStore& store, RemoteProcess* process)
+ : AddressSpace(process), page_store_(store), num_state_(num_state)
{
XBT_DEBUG("Taking snapshot %ld", num_state);
else if (type == RegionType::Heap)
xbt_assert(not object_info, "Unexpected object info for heap region.");
- auto* region = new Region(type, start_addr, size);
+ auto* region = new Region(page_store_, type, start_addr, size);
region->object_info(object_info);
snapshot_regions_.push_back(std::unique_ptr<Region>(region));
}
using hash_type = std::uint64_t;
class XBT_PRIVATE Snapshot final : public AddressSpace {
+ PageStore& page_store_;
+
public:
/* Initialization */
- Snapshot(long num_state, RemoteProcess* process = &mc_model_checker->get_remote_process());
+ Snapshot(long num_state, PageStore& store, RemoteProcess* process = &mc_model_checker->get_remote_process());
/* Regular use */
bool on_heap(const void* address) const
/**************** Class BOOST_tests *************************/
using simgrid::mc::Region;
class snap_test_helper {
+ static simgrid::mc::PageStore page_store_;
+
public:
static void init_memory(void* mem, size_t size);
static void Init();
// static member variables init.
std::unique_ptr<simgrid::mc::RemoteProcess> snap_test_helper::process = nullptr;
+simgrid::mc::PageStore snap_test_helper::page_store_(500);
void snap_test_helper::init_memory(void* mem, size_t size)
{
// Init memory and take snapshots:
init_memory(source, byte_size);
- auto* region0 = new simgrid::mc::Region(simgrid::mc::RegionType::Data, source, byte_size);
+ auto* region0 = new simgrid::mc::Region(page_store_, simgrid::mc::RegionType::Data, source, byte_size);
for (int i = 0; i < n; i += 2) {
init_memory((char*)source + i * xbt_pagesize, xbt_pagesize);
}
- auto* region = new simgrid::mc::Region(simgrid::mc::RegionType::Data, source, byte_size);
+ auto* region = new simgrid::mc::Region(page_store_, simgrid::mc::RegionType::Data, source, byte_size);
void* destination = mmap(nullptr, byte_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
INFO("Could not allocate destination memory");
{
prologue_return ret = prologue(1);
memcpy(ret.src, &mc_model_checker, sizeof(void*));
- const simgrid::mc::Region region2(simgrid::mc::RegionType::Data, ret.src, ret.size);
+ const simgrid::mc::Region region2(page_store_, simgrid::mc::RegionType::Data, ret.src, ret.size);
INFO("Mismtach in MC_region_read_pointer()");
REQUIRE(MC_region_read_pointer(®ion2, ret.src) == mc_model_checker);