From: Gabriel Corona Date: Thu, 23 Jun 2016 09:33:49 +0000 (+0200) Subject: Fix compilation of MC X-Git-Tag: v3_14~890 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/742074df00e1d14c35f8505924d26036b9b8cac5 Fix compilation of MC --- diff --git a/src/mc/AddressSpace.hpp b/src/mc/AddressSpace.hpp index c3d1e70b3a..2fc18eab35 100644 --- a/src/mc/AddressSpace.hpp +++ b/src/mc/AddressSpace.hpp @@ -95,51 +95,6 @@ public: static constexpr ReadOptions lazy() { return ReadOptions(1); } }; -/** HACK, A value from another process - * - * This represents a value from another process: - * - * * constructor/destructor are disabled; - * - * * raw memory copy (std::memcpy) is used to copy Remote; - * - * * raw memory comparison is used to compare them; - * - * * when T is a trivial type, Remote is convertible to a T. - * - * We currently only handle the case where the type has the same layout - * in the current process and in the target process: we don't handle - * cross-architecture (such as 32-bit/64-bit access). - */ -template -union Remote { -private: - T buffer; -public: - Remote() {} - ~Remote() {} - Remote(Remote const& that) - { - std::memcpy(&buffer, &that.buffer, sizeof(buffer)); - } - Remote& operator=(Remote const& that) - { - std::memcpy(&buffer, &that.buffer, sizeof(buffer)); - return *this; - } - T* getBuffer() { return &buffer; } - const T* getBuffer() const { return &buffer; } - std::size_t getBufferSize() const { return sizeof(T); } - operator T() const { - static_assert(std::is_trivial::value, "Cannot convert non trivial type"); - return buffer; - } - void clear() - { - std::memset(static_cast(&buffer), 0, sizeof(T)); - } -}; - /** A given state of a given process (abstract base class) * * Currently, this might either be: diff --git a/src/mc/Process.hpp b/src/mc/Process.hpp index e797a0a106..23d262081e 100644 --- a/src/mc/Process.hpp +++ b/src/mc/Process.hpp @@ -109,15 +109,20 @@ public: const void* read_bytes(void* buffer, std::size_t size, RemotePtr address, int process_index = ProcessIndexAny, ReadOptions options = ReadOptions::none()) const override; + void read_variable(const char* name, void* target, size_t size) const; + template void read_variable(const char* name, T* target) const + { + read_variable(name, target, sizeof(*target)); + } template - T read_variable(const char *name) const + Remote read_variable(const char *name) const { - static_assert(std::is_trivial::value, "Cannot read a non-trivial type"); - T res; - read_variable(name, &res, sizeof(T)); + Remote res; + read_variable(name, res.getBuffer(), sizeof(T)); return res; } + std::string read_string(RemotePtr address) const; std::string read_string(RemotePtr address, std::size_t len) const { diff --git a/src/mc/RemotePtr.hpp b/src/mc/RemotePtr.hpp index 23d03729dc..5c11ddc1c5 100644 --- a/src/mc/RemotePtr.hpp +++ b/src/mc/RemotePtr.hpp @@ -7,11 +7,76 @@ #ifndef SIMGRID_MC_REMOTE_PTR_HPP #define SIMGRID_MC_REMOTE_PTR_HPP +#include #include +#include + +#include +#include namespace simgrid { namespace mc { +template +struct pointer_to_data_member {}; +template +struct pointer_to_data_member::value || std::is_class::value >::type> { + typedef T M::* type; +}; + +template +using pointer_to_data_member_t = typename pointer_to_data_member::type; + +/** HACK, A value from another process + * + * This represents a value from another process: + * + * * constructor/destructor are disabled; + * + * * raw memory copy (std::memcpy) is used to copy Remote; + * + * * raw memory comparison is used to compare them; + * + * * when T is a trivial type, Remote is convertible to a T. + * + * We currently only handle the case where the type has the same layout + * in the current process and in the target process: we don't handle + * cross-architecture (such as 32-bit/64-bit access). + */ +template +union Remote { +private: + T buffer; +public: + Remote() {} + ~Remote() {} + Remote(T& p) + { + std::memcpy(&buffer, &p, sizeof(buffer)); + } + Remote(Remote const& that) + { + std::memcpy(&buffer, &that.buffer, sizeof(buffer)); + } + Remote& operator=(Remote const& that) + { + std::memcpy(&buffer, &that.buffer, sizeof(buffer)); + return *this; + } + T* getBuffer() { return &buffer; } + const T* getBuffer() const { return &buffer; } + std::size_t getBufferSize() const { return sizeof(T); } + operator T() const { + static_assert(std::is_trivial::value, "Cannot convert non trivial type"); + return buffer; + } + void clear() + { + std::memset(static_cast(&buffer), 0, sizeof(T)); + } + +}; + /** Pointer to a remote address-space (process, snapshot) * * With this we can clearly identify the expected type of an address in the @@ -32,12 +97,13 @@ public: RemotePtr() : address_(0) {} RemotePtr(std::uint64_t address) : address_(address) {} RemotePtr(T* address) : address_((std::uintptr_t)address) {} + RemotePtr(Remote p) : RemotePtr(*p.getBuffer()) {} std::uint64_t address() const { return address_; } /** Turn into a local pointer * (if the remote process is not, in fact, remote) */ - T* local() { return (T*) address_; } + T* local() const { return (T*) address_; } operator bool() const { diff --git a/src/mc/mc_smx.cpp b/src/mc/mc_smx.cpp index 09571a13cd..0c6b8398a1 100644 --- a/src/mc/mc_smx.cpp +++ b/src/mc/mc_smx.cpp @@ -45,13 +45,14 @@ simgrid::mc::SimixProcessInformation* process_info_cast(smx_process_t p) */ static void MC_process_refresh_simix_process_list( simgrid::mc::Process* process, - std::vector& target, xbt_swag_t remote_swag) + std::vector& target, + simgrid::mc::RemotePtr remote_swag) { target.clear(); // swag = REMOTE(*simix_global->process_list) s_xbt_swag_t swag; - process->read_bytes(&swag, sizeof(swag), remote(remote_swag)); + process->read_bytes(&swag, sizeof(swag), remote_swag); // Load each element of the vector from the MCed process: int i = 0; @@ -79,19 +80,27 @@ void Process::refresh_simix() // TODO, avoid to reload `&simix_global`, `simix_global`, `*simix_global` - // simix_global_p = REMOTE(simix_global); - smx_global_t simix_global_p; - this->read_variable("simix_global", &simix_global_p, sizeof(simix_global_p)); + static_assert(std::is_same< + std::unique_ptr, + decltype(simix_global) + >::value, "Unexpected type for simix_global"); + static_assert(sizeof(simix_global) == sizeof(simgrid::simix::Global*), + "Bad size for simix_global"); + + // simix_global_p = REMOTE(simix_global.get()); + RemotePtr simix_global_p = + this->read_variable("simix_global"); // simix_global = REMOTE(*simix_global) - union { simgrid::simix::Global simix_global }; - this->read_bytes(&simix_global, sizeof(simix_global), - remote(simix_global_p)); + Remote simix_global = + this->read(simix_global_p); MC_process_refresh_simix_process_list( - this, this->smx_process_infos, simix_global.process_list); + this, this->smx_process_infos, + remote(simix_global.getBuffer()->process_list)); MC_process_refresh_simix_process_list( - this, this->smx_old_process_infos, simix_global.process_to_destroy); + this, this->smx_old_process_infos, + remote(simix_global.getBuffer()->process_to_destroy)); this->cache_flags_ |= Process::cache_simix_processes; }