From 54b039b2cb830d851ebe173aaad0a2bbf3129174 Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Tue, 2 Jun 2015 13:28:09 +0200 Subject: [PATCH] [mc] Fix compilation error on clang (and group all the region creation functions together) error: 'MC_region_sparse' has C-linkage specified, but returns user-defined type 'simgrid::mc::RegionSnapshot' which is incompatible with C --- buildtools/Cmake/DefinePackages.cmake | 2 + src/mc/RegionSnapshot.cpp | 77 +++++++ src/mc/RegionSnapshot.hpp | 279 ++++++++++++++++++++++++++ src/mc/mc_checkpoint.cpp | 65 +----- src/mc/mc_snapshot.h | 270 +------------------------ 5 files changed, 360 insertions(+), 333 deletions(-) create mode 100644 src/mc/RegionSnapshot.cpp create mode 100644 src/mc/RegionSnapshot.hpp diff --git a/buildtools/Cmake/DefinePackages.cmake b/buildtools/Cmake/DefinePackages.cmake index 9efb8bf973..ea972cb9a2 100644 --- a/buildtools/Cmake/DefinePackages.cmake +++ b/buildtools/Cmake/DefinePackages.cmake @@ -606,6 +606,8 @@ set(MC_SRC src/mc/mc_checkpoint.cpp src/mc/mc_snapshot.h src/mc/mc_snapshot.cpp + src/mc/RegionSnapshot.cpp + src/mc/RegionSnapshot.hpp src/mc/PageStore.hpp src/mc/PageStore.cpp src/mc/mc_page_snapshot.cpp diff --git a/src/mc/RegionSnapshot.cpp b/src/mc/RegionSnapshot.cpp new file mode 100644 index 0000000000..3d1daa4dbc --- /dev/null +++ b/src/mc/RegionSnapshot.cpp @@ -0,0 +1,77 @@ +/* Copyright (c) 2007-2015. 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 "mc/mc.h" +#include "mc_snapshot.h" +#include "RegionSnapshot.hpp" + +extern "C" { + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_RegionSnaphot, mc, + "Logging specific to region snapshots"); + +} + +namespace simgrid { +namespace mc { + +RegionSnapshot dense_region( + mc_region_type_t region_type, + void *start_addr, void* permanent_addr, size_t size) +{ + std::vector data(size); + mc_model_checker->process().read_bytes(data.data(), size, + remote(permanent_addr), + simgrid::mc::ProcessIndexDisabled); + + simgrid::mc::RegionSnapshot region( + region_type, start_addr, permanent_addr, size); + region.flat_data(std::move(data)); + + XBT_DEBUG("New region : type : %d, data : %p (real addr %p), size : %zu", + region_type, region.flat_data().data(), permanent_addr, size); + return std::move(region); +} + +/** @brief Take a snapshot of a given region + * + * @param type + * @param start_addr Address of the region in the simulated process + * @param permanent_addr Permanent address of this data (for privatized variables, this is the virtual address of the privatized mapping) + * @param size Size of the data* + */ +RegionSnapshot region( + mc_region_type_t 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); + } +} + +RegionSnapshot sparse_region(mc_region_type_t region_type, + void *start_addr, void* permanent_addr, size_t size) +{ + mc_process_t process = &mc_model_checker->process(); + + 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 = mc_page_count(size); + + simgrid::mc::PerPageCopy page_data(mc_model_checker->page_store(), *process, + permanent_addr, page_count); + + simgrid::mc::RegionSnapshot region( + region_type, start_addr, permanent_addr, size); + region.page_data(std::move(page_data)); + return std::move(region); +} + +} +} diff --git a/src/mc/RegionSnapshot.hpp b/src/mc/RegionSnapshot.hpp new file mode 100644 index 0000000000..0c85f22eb3 --- /dev/null +++ b/src/mc/RegionSnapshot.hpp @@ -0,0 +1,279 @@ +/* Copyright (c) 2007-2015. 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 +#include + +#include "PageStore.hpp" +#include "AddressSpace.hpp" + +#ifndef SIMGRID_MC_REGION_SNAPSHOT_HPP +#define SIMGRID_MC_REGION_SNAPSHOT_HPP + +typedef enum e_mc_region_type_t { + MC_REGION_TYPE_UNKNOWN = 0, + MC_REGION_TYPE_HEAP = 1, + MC_REGION_TYPE_DATA = 2 +} mc_region_type_t; + +// TODO, use OO instead of this +typedef enum e_mc_region_storage_type_t { + MC_REGION_STORAGE_TYPE_NONE = 0, + MC_REGION_STORAGE_TYPE_FLAT = 1, + MC_REGION_STORAGE_TYPE_CHUNKED = 2, + MC_REGION_STORAGE_TYPE_PRIVATIZED = 3 +} mc_region_storage_type_t; + +namespace simgrid { +namespace mc { + +class PerPageCopy { + PageStore* store_; + std::vector pagenos_; +public: + PerPageCopy() : store_(nullptr) {} + PerPageCopy(PerPageCopy const& that) + { + store_ = that.store_; + pagenos_ = that.pagenos_; + for (std::size_t pageno : pagenos_) + store_->ref_page(pageno); + } + void clear() + { + for (std::size_t pageno : pagenos_) + store_->unref_page(pageno); + pagenos_.clear(); + } + ~PerPageCopy() { + clear(); + } + + PerPageCopy(PerPageCopy&& that) + { + store_ = that.store_; + that.store_ = nullptr; + pagenos_ = std::move(that.pagenos_); + that.pagenos_.clear(); + } + PerPageCopy& operator=(PerPageCopy const& that) + { + this->clear(); + store_ = that.store_; + pagenos_ = that.pagenos_; + for (std::size_t pageno : pagenos_) + store_->ref_page(pageno); + return *this; + } + PerPageCopy& operator=(PerPageCopy && that) + { + this->clear(); + store_ = that.store_; + that.store_ = nullptr; + pagenos_ = std::move(that.pagenos_); + that.pagenos_.clear(); + return *this; + } + + std::size_t page_count() const + { + return pagenos_.size(); + } + + std::size_t pageno(std::size_t i) const + { + return pagenos_[i]; + } + + const void* page(std::size_t i) const + { + return store_->get_page(pagenos_[i]); + } + + PerPageCopy(PageStore& store, AddressSpace& as, + remote_ptr addr, std::size_t page_count); +}; + +/** @brief Copy/snapshot of a given memory region + * + * Different types of region snapshot storage types exist: + *
    + *
  • flat/dense snapshots are a simple copy of the region;
  • + *
  • sparse/per-page snapshots are snaapshots which shared + * identical pages.
  • + *
  • privatized (SMPI global variable privatisation). + *
+ * + * This is handled with a variant based approch: + * + * * `storage_type` identified the type of storage; + * * an anonymous enum is used to distinguish the relevant types for + * each type. + */ +class RegionSnapshot { +private: + mc_region_type_t region_type_; + mc_region_storage_type_t storage_type_; + mc_object_info_t object_info_; + + /** @brief Virtual address of the region in the simulated process */ + void *start_addr_; + + /** @brief Size of the data region in bytes */ + size_t size_; + + /** @brief Permanent virtual address of the region + * + * This is usually the same address as the simuilated process address. + * However, when using SMPI privatization of global variables, + * each SMPI process has its own set of global variables stored + * at a different virtual address. The scheduler maps those region + * on the region of the global variables. + * + * */ + void *permanent_addr_; + + std::vector flat_data_; + PerPageCopy page_numbers_; + std::vector privatized_regions_; +public: + RegionSnapshot() : + region_type_(MC_REGION_TYPE_UNKNOWN), + storage_type_(MC_REGION_STORAGE_TYPE_NONE), + object_info_(nullptr), + start_addr_(nullptr), + size_(0), + permanent_addr_(nullptr) + {} + RegionSnapshot(mc_region_type_t type, void *start_addr, void* permanent_addr, size_t size) : + region_type_(type), + storage_type_(MC_REGION_STORAGE_TYPE_NONE), + object_info_(nullptr), + start_addr_(start_addr), + size_(size), + permanent_addr_(permanent_addr) + {} + ~RegionSnapshot() {} + RegionSnapshot(RegionSnapshot const&) = default; + RegionSnapshot& operator=(RegionSnapshot const&) = default; + RegionSnapshot(RegionSnapshot&& that) + { + region_type_ = that.region_type_; + storage_type_ = that.storage_type_; + object_info_ = that.object_info_; + start_addr_ = that.start_addr_; + size_ = that.size_; + permanent_addr_ = that.permanent_addr_; + flat_data_ = std::move(that.flat_data_); + page_numbers_ = std::move(that.page_numbers_); + privatized_regions_ = std::move(that.privatized_regions_); + that.clear(); + } + RegionSnapshot& operator=(RegionSnapshot&& that) + { + region_type_ = that.region_type_; + storage_type_ = that.storage_type_; + object_info_ = that.object_info_; + start_addr_ = that.start_addr_; + size_ = that.size_; + permanent_addr_ = that.permanent_addr_; + flat_data_ = std::move(that.flat_data_); + page_numbers_ = std::move(that.page_numbers_); + privatized_regions_ = std::move(that.privatized_regions_); + that.clear(); + return *this; + } + + // Data + + void clear() + { + region_type_ = MC_REGION_TYPE_UNKNOWN; + storage_type_ = MC_REGION_STORAGE_TYPE_NONE; + privatized_regions_.clear(); + page_numbers_.clear(); + flat_data_.clear(); + object_info_ = nullptr; + start_addr_ = nullptr; + size_ = 0; + permanent_addr_ = nullptr; + } + + void clear_data() + { + storage_type_ = MC_REGION_STORAGE_TYPE_NONE; + flat_data_.clear(); + page_numbers_.clear(); + privatized_regions_.clear(); + } + + void flat_data(std::vector data) + { + storage_type_ = MC_REGION_STORAGE_TYPE_FLAT; + flat_data_ = std::move(data); + page_numbers_.clear(); + privatized_regions_.clear(); + } + std::vector const& flat_data() const { return flat_data_; } + + void page_data(PerPageCopy page_data) + { + storage_type_ = MC_REGION_STORAGE_TYPE_CHUNKED; + flat_data_.clear(); + page_numbers_ = std::move(page_data); + privatized_regions_.clear(); + } + PerPageCopy const& page_data() const { return page_numbers_; } + + void privatized_data(std::vector data) + { + storage_type_ = MC_REGION_STORAGE_TYPE_PRIVATIZED; + flat_data_.clear(); + page_numbers_.clear(); + privatized_regions_ = std::move(data); + } + std::vector const& privatized_data() const + { + return privatized_regions_; + } + std::vector& privatized_data() + { + return privatized_regions_; + } + + mc_object_info_t object_info() const { return object_info_; } + void object_info(mc_object_info_t info) { object_info_ = info; } + + // Other getters + + remote_ptr start() const { return remote(start_addr_); } + remote_ptr end() const { return remote((char*)start_addr_ + size_); } + remote_ptr permanent_address() const { return remote(permanent_addr_); } + std::size_t size() const { return size_; } + mc_region_storage_type_t storage_type() const { return storage_type_; } + mc_region_type_t region_type() const { return region_type_; } + + bool contain(remote_ptr p) const + { + return p >= start() && p < end(); + } +}; + +simgrid::mc::RegionSnapshot privatized_region( + mc_region_type_t type, void *start_addr, void* data_addr, size_t size); +simgrid::mc::RegionSnapshot dense_region( + mc_region_type_t type, void *start_addr, void* data_addr, size_t size); +simgrid::mc::RegionSnapshot sparse_region( + mc_region_type_t type, void *start_addr, void* data_addr, size_t size); +simgrid::mc::RegionSnapshot region( + mc_region_type_t type, void *start_addr, void* data_addr, size_t size); + +} +} + +typedef class simgrid::mc::RegionSnapshot s_mc_mem_region_t, *mc_mem_region_t; + +#endif diff --git a/src/mc/mc_checkpoint.cpp b/src/mc/mc_checkpoint.cpp index 6e4b110b2f..f813c74688 100644 --- a/src/mc/mc_checkpoint.cpp +++ b/src/mc/mc_checkpoint.cpp @@ -75,69 +75,6 @@ static void local_variable_free_voidp(void *v) } -namespace simgrid { -namespace mc { - -RegionSnapshot::~RegionSnapshot() {} - -simgrid::mc::RegionSnapshot dense_region( - mc_region_type_t region_type, - void *start_addr, void* permanent_addr, size_t size) -{ - std::vector data(size); - mc_model_checker->process().read_bytes(data.data(), size, - remote(permanent_addr), - simgrid::mc::ProcessIndexDisabled); - - simgrid::mc::RegionSnapshot region( - region_type, start_addr, permanent_addr, size); - region.flat_data(std::move(data)); - - XBT_DEBUG("New region : type : %d, data : %p (real addr %p), size : %zu", - region_type, region.flat_data().data(), permanent_addr, size); - return std::move(region); -} - -/** @brief Take a snapshot of a given region - * - * @param type - * @param start_addr Address of the region in the simulated process - * @param permanent_addr Permanent address of this data (for privatized variables, this is the virtual address of the privatized mapping) - * @param size Size of the data* - */ -static simgrid::mc::RegionSnapshot region( - mc_region_type_t 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); - } -} - -simgrid::mc::RegionSnapshot sparse_region(mc_region_type_t region_type, - void *start_addr, void* permanent_addr, size_t size) -{ - mc_process_t process = &mc_model_checker->process(); - - 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 = mc_page_count(size); - - simgrid::mc::PerPageCopy page_data(mc_model_checker->page_store(), *process, - permanent_addr, page_count); - - simgrid::mc::RegionSnapshot region( - region_type, start_addr, permanent_addr, size); - region.page_data(std::move(page_data)); - return std::move(region); -} - -} -} - extern "C" { /** @brief Restore a region from a snapshot @@ -221,7 +158,7 @@ static void MC_snapshot_add_region(int index, mc_snapshot_t snapshot, mc_region_ simgrid::mc::RegionSnapshot region; if (privatization_aware && MC_smpi_process_count()) - region = MC_region_privatized(type, start_addr, permanent_addr, size); + region = simgrid::mc::privatized_region(type, start_addr, permanent_addr, size); else region = simgrid::mc::region(type, start_addr, permanent_addr, size); diff --git a/src/mc/mc_snapshot.h b/src/mc/mc_snapshot.h index a6a4cde12b..87e007f402 100644 --- a/src/mc/mc_snapshot.h +++ b/src/mc/mc_snapshot.h @@ -21,280 +21,12 @@ #include "mc_mmalloc.h" #include "mc/AddressSpace.hpp" #include "mc_unw.h" +#include "RegionSnapshot.hpp" SG_BEGIN_DECL() // ***** Snapshot region -typedef enum e_mc_region_type_t { - MC_REGION_TYPE_UNKNOWN = 0, - MC_REGION_TYPE_HEAP = 1, - MC_REGION_TYPE_DATA = 2 -} mc_region_type_t; - -// TODO, use OO instead of this -typedef enum e_mc_region_storage_type_t { - MC_REGION_STORAGE_TYPE_NONE = 0, - MC_REGION_STORAGE_TYPE_FLAT = 1, - MC_REGION_STORAGE_TYPE_CHUNKED = 2, - MC_REGION_STORAGE_TYPE_PRIVATIZED = 3 -} mc_region_storage_type_t; - -namespace simgrid { -namespace mc { - -class PerPageCopy { - PageStore* store_; - std::vector pagenos_; -public: - PerPageCopy() : store_(nullptr) {} - PerPageCopy(PerPageCopy const& that) - { - store_ = that.store_; - pagenos_ = that.pagenos_; - for (std::size_t pageno : pagenos_) - store_->ref_page(pageno); - } - void clear() - { - for (std::size_t pageno : pagenos_) - store_->unref_page(pageno); - pagenos_.clear(); - } - ~PerPageCopy() { - clear(); - } - - PerPageCopy(PerPageCopy&& that) - { - store_ = that.store_; - that.store_ = nullptr; - pagenos_ = std::move(that.pagenos_); - that.pagenos_.clear(); - } - PerPageCopy& operator=(PerPageCopy const& that) - { - this->clear(); - store_ = that.store_; - pagenos_ = that.pagenos_; - for (std::size_t pageno : pagenos_) - store_->ref_page(pageno); - return *this; - } - PerPageCopy& operator=(PerPageCopy && that) - { - this->clear(); - store_ = that.store_; - that.store_ = nullptr; - pagenos_ = std::move(that.pagenos_); - that.pagenos_.clear(); - return *this; - } - - std::size_t page_count() const - { - return pagenos_.size(); - } - - std::size_t pageno(std::size_t i) const - { - return pagenos_[i]; - } - - const void* page(std::size_t i) const - { - return store_->get_page(pagenos_[i]); - } - - PerPageCopy(PageStore& store, AddressSpace& as, - remote_ptr addr, std::size_t page_count); -}; - -/** @brief Copy/snapshot of a given memory region - * - * Different types of region snapshot storage types exist: - *
    - *
  • flat/dense snapshots are a simple copy of the region;
  • - *
  • sparse/per-page snapshots are snaapshots which shared - * identical pages.
  • - *
  • privatized (SMPI global variable privatisation). - *
- * - * This is handled with a variant based approch: - * - * * `storage_type` identified the type of storage; - * * an anonymous enum is used to distinguish the relevant types for - * each type. - */ -class RegionSnapshot { -private: - mc_region_type_t region_type_; - mc_region_storage_type_t storage_type_; - mc_object_info_t object_info_; - - /** @brief Virtual address of the region in the simulated process */ - void *start_addr_; - - /** @brief Size of the data region in bytes */ - size_t size_; - - /** @brief Permanent virtual address of the region - * - * This is usually the same address as the simuilated process address. - * However, when using SMPI privatization of global variables, - * each SMPI process has its own set of global variables stored - * at a different virtual address. The scheduler maps those region - * on the region of the global variables. - * - * */ - void *permanent_addr_; - - std::vector flat_data_; - PerPageCopy page_numbers_; - std::vector privatized_regions_; -public: - RegionSnapshot() : - region_type_(MC_REGION_TYPE_UNKNOWN), - storage_type_(MC_REGION_STORAGE_TYPE_NONE), - object_info_(nullptr), - start_addr_(nullptr), - size_(0), - permanent_addr_(nullptr) - {} - RegionSnapshot(mc_region_type_t type, void *start_addr, void* permanent_addr, size_t size) : - region_type_(type), - storage_type_(MC_REGION_STORAGE_TYPE_NONE), - object_info_(nullptr), - start_addr_(start_addr), - size_(size), - permanent_addr_(permanent_addr) - {} - ~RegionSnapshot(); - RegionSnapshot(RegionSnapshot const&) = default; - RegionSnapshot& operator=(RegionSnapshot const&) = default; - RegionSnapshot(RegionSnapshot&& that) - { - region_type_ = that.region_type_; - storage_type_ = that.storage_type_; - object_info_ = that.object_info_; - start_addr_ = that.start_addr_; - size_ = that.size_; - permanent_addr_ = that.permanent_addr_; - flat_data_ = std::move(that.flat_data_); - page_numbers_ = std::move(that.page_numbers_); - privatized_regions_ = std::move(that.privatized_regions_); - that.clear(); - } - RegionSnapshot& operator=(RegionSnapshot&& that) - { - region_type_ = that.region_type_; - storage_type_ = that.storage_type_; - object_info_ = that.object_info_; - start_addr_ = that.start_addr_; - size_ = that.size_; - permanent_addr_ = that.permanent_addr_; - flat_data_ = std::move(that.flat_data_); - page_numbers_ = std::move(that.page_numbers_); - privatized_regions_ = std::move(that.privatized_regions_); - that.clear(); - return *this; - } - - // Data - - void clear() - { - region_type_ = MC_REGION_TYPE_UNKNOWN; - storage_type_ = MC_REGION_STORAGE_TYPE_NONE; - privatized_regions_.clear(); - page_numbers_.clear(); - flat_data_.clear(); - object_info_ = nullptr; - start_addr_ = nullptr; - size_ = 0; - permanent_addr_ = nullptr; - } - - void clear_data() - { - storage_type_ = MC_REGION_STORAGE_TYPE_NONE; - flat_data_.clear(); - page_numbers_.clear(); - privatized_regions_.clear(); - } - - void flat_data(std::vector data) - { - storage_type_ = MC_REGION_STORAGE_TYPE_FLAT; - flat_data_ = std::move(data); - page_numbers_.clear(); - privatized_regions_.clear(); - } - std::vector const& flat_data() const { return flat_data_; } - - void page_data(PerPageCopy page_data) - { - storage_type_ = MC_REGION_STORAGE_TYPE_CHUNKED; - flat_data_.clear(); - page_numbers_ = std::move(page_data); - privatized_regions_.clear(); - } - PerPageCopy const& page_data() const { return page_numbers_; } - - void privatized_data(std::vector data) - { - storage_type_ = MC_REGION_STORAGE_TYPE_PRIVATIZED; - flat_data_.clear(); - page_numbers_.clear(); - privatized_regions_ = std::move(data); - } - std::vector const& privatized_data() const - { - return privatized_regions_; - } - std::vector& privatized_data() - { - return privatized_regions_; - } - - mc_object_info_t object_info() const { return object_info_; } - void object_info(mc_object_info_t info) { object_info_ = info; } - - // Other getters - - remote_ptr start() const { return remote(start_addr_); } - remote_ptr end() const { return remote((char*)start_addr_ + size_); } - remote_ptr permanent_address() const { return remote(permanent_addr_); } - std::size_t size() const { return size_; } - mc_region_storage_type_t storage_type() const { return storage_type_; } - mc_region_type_t region_type() const { return region_type_; } - - bool contain(remote_ptr p) const - { - return p >= start() && p < end(); - } -}; - -simgrid::mc::RegionSnapshot privatized_region( - mc_region_type_t type, void *start_addr, void* data_addr, size_t size); -simgrid::mc::RegionSnapshot dense_region( - mc_region_type_t type, void *start_addr, void* data_addr, size_t size); -simgrid::mc::RegionSnapshot sparse_region( - mc_region_type_t type, void *start_addr, void* data_addr, size_t size); -simgrid::mc::RegionSnapshot region( - mc_region_type_t type, void *start_addr, void* data_addr, size_t size); - -} -} - -typedef class simgrid::mc::RegionSnapshot s_mc_mem_region_t, *mc_mem_region_t; - -namespace simgrid { -namespace mc { - -} -} - XBT_INTERNAL void mc_region_restore_sparse(mc_process_t process, mc_mem_region_t reg); static inline __attribute__ ((always_inline)) -- 2.20.1