X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/96cedde3cdbc0b8ffc3f096a1b65d021b0226f99..76a0084bc896c39bbe5748832ef5e7addf680994:/src/mc/sosp/RegionSnapshot.cpp diff --git a/src/mc/sosp/RegionSnapshot.cpp b/src/mc/sosp/RegionSnapshot.cpp index ea2445ffe2..4088d43a3c 100644 --- a/src/mc/sosp/RegionSnapshot.cpp +++ b/src/mc/sosp/RegionSnapshot.cpp @@ -10,11 +10,11 @@ #define MAP_POPULATE MAP_PREFAULT_READ #endif -#include "mc/mc.h" +#include "src/mc/ModelChecker.hpp" #include "src/mc/mc_config.hpp" -#include "src/mc/sosp/mc_snapshot.hpp" +#include "src/mc/mc_forward.hpp" -#include "src/mc/sosp/ChunkedData.hpp" +#include "src/mc/mc_smx.hpp" #include "src/mc/sosp/RegionSnapshot.hpp" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_RegionSnaphot, mc, "Logging specific to region snapshots"); @@ -22,86 +22,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_RegionSnaphot, mc, "Logging specific to regio namespace simgrid { namespace mc { -static inline const char* to_cstr(RegionType region) -{ - switch (region) { - case RegionType::Unknown: - return "unknown"; - case RegionType::Heap: - return "Heap"; - case RegionType::Data: - return "Data"; - default: - return "?"; - } -} - -Buffer::Buffer(std::size_t size, Type type) : size_(size), type_(type) -{ - switch (type_) { - case Type::Malloc: - data_ = ::operator new(size_); - break; - case Type::Mmap: - data_ = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0); - if (data_ == MAP_FAILED) { - data_ = nullptr; - size_ = 0; - type_ = Type::Malloc; - throw std::bad_alloc(); - } - break; - default: - abort(); - } -} - -void Buffer::clear() noexcept -{ - switch (type_) { - case Type::Malloc: - ::operator delete(data_); - break; - case Type::Mmap: - if (munmap(data_, size_) != 0) - abort(); - break; - default: - abort(); - } - data_ = nullptr; - size_ = 0; - type_ = Type::Malloc; -} - -RegionSnapshot dense_region(RegionType region_type, void* start_addr, void* permanent_addr, size_t size) -{ - // When KSM support is enables, we allocate memory using mmap: - // * we don't want to advise bits of the heap as mergable - // * mmap gives data aligned on page boundaries which is merge friendly - simgrid::mc::Buffer data; - if (_sg_mc_ksm) - data = Buffer::mmap(size); - else - data = Buffer::malloc(size); - - mc_model_checker->process().read_bytes(data.get(), size, remote(permanent_addr), simgrid::mc::ProcessIndexDisabled); - -#ifdef __linux__ - if (_sg_mc_ksm) - // Mark the region as mergeable *after* we have written into it. - // Trying to merge them before is useless/counterproductive. - madvise(data.get(), size, MADV_MERGEABLE); -#endif - - simgrid::mc::RegionSnapshot region(region_type, start_addr, permanent_addr, size); - region.flat_data(std::move(data)); - - XBT_DEBUG("New region : type : %s, data : %p (real addr %p), size : %zu", to_cstr(region_type), - region.flat_data().get(), permanent_addr, size); - return region; -} - /** @brief Take a snapshot of a given region * * @param type @@ -110,29 +30,38 @@ RegionSnapshot dense_region(RegionType region_type, void* start_addr, void* perm * privatized mapping) * @param size Size of the data* */ -RegionSnapshot region(RegionType type, void* start_addr, void* permanent_addr, size_t size) +RegionSnapshot* region(RegionType type, void* start_addr, void* permanent_addr, size_t size) { - if (_sg_mc_sparse_checkpoint) - return sparse_region(type, start_addr, permanent_addr, size); - else - return dense_region(type, start_addr, permanent_addr, size); + return new RegionSnapshot(type, start_addr, permanent_addr, size); } -RegionSnapshot sparse_region(RegionType region_type, void* start_addr, void* permanent_addr, size_t size) +RegionSnapshot::RegionSnapshot(RegionType region_type, void* start_addr, void* permanent_addr, size_t size) + : region_type_(region_type), start_addr_(start_addr), size_(size), permanent_addr_(permanent_addr) { simgrid::mc::RemoteClient* process = &mc_model_checker->process(); - assert(process != nullptr); - xbt_assert((((uintptr_t)start_addr) & (xbt_pagesize - 1)) == 0, "Not at the beginning of a page"); - xbt_assert((((uintptr_t)permanent_addr) & (xbt_pagesize - 1)) == 0, "Not at the beginning of a page"); - size_t page_count = simgrid::mc::mmu::chunkCount(size); + xbt_assert((((uintptr_t)start_addr) & (xbt_pagesize - 1)) == 0, "Start address not at the beginning of a page"); + xbt_assert((((uintptr_t)permanent_addr) & (xbt_pagesize - 1)) == 0, + "Permanent address not at the beginning of a page"); - simgrid::mc::ChunkedData page_data(mc_model_checker->page_store(), *process, RemotePtr(permanent_addr), - page_count); + page_numbers_ = + ChunkedData(mc_model_checker->page_store(), *process, RemotePtr(permanent_addr), mmu::chunk_count(size)); +} + +/** @brief Restore a region from a snapshot + * + * @param region Target region + */ +void RegionSnapshot::restore() +{ + xbt_assert(((permanent_address().address()) & (xbt_pagesize - 1)) == 0, "Not at the beginning of a page"); + xbt_assert(simgrid::mc::mmu::chunk_count(size()) == page_data().page_count()); - simgrid::mc::RegionSnapshot region(region_type, start_addr, permanent_addr, size); - region.page_data(std::move(page_data)); - return region; + for (size_t i = 0; i != page_data().page_count(); ++i) { + void* target_page = (void*)simgrid::mc::mmu::join(i, (std::uintptr_t)(void*)permanent_address().address()); + const void* source_page = page_data().page(i); + mc_model_checker->process().write_bytes(source_page, xbt_pagesize, remote(target_page)); + } } } // namespace mc