Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix compilation of MC
authorGabriel Corona <gabriel.corona@loria.fr>
Thu, 23 Jun 2016 09:33:49 +0000 (11:33 +0200)
committerGabriel Corona <gabriel.corona@loria.fr>
Thu, 23 Jun 2016 09:33:53 +0000 (11:33 +0200)
src/mc/AddressSpace.hpp
src/mc/Process.hpp
src/mc/RemotePtr.hpp
src/mc/mc_smx.cpp

index c3d1e70..2fc18ea 100644 (file)
@@ -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<T>;
- *
- *  * 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<class T>
-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<T>::value, "Cannot convert non trivial type");
-    return buffer;
-  }
-  void clear()
-  {
-    std::memset(static_cast<void*>(&buffer), 0, sizeof(T));
-  }
-};
-
 /** A given state of a given process (abstract base class)
  *
  *  Currently, this might either be:
index e797a0a..23d2620 100644 (file)
@@ -109,15 +109,20 @@ public:
   const void* read_bytes(void* buffer, std::size_t size,
     RemotePtr<void> address, int process_index = ProcessIndexAny,
     ReadOptions options = ReadOptions::none()) const override;
+
   void read_variable(const char* name, void* target, size_t size) const;
+  template<class T> void read_variable(const char* name, T* target) const
+  {
+    read_variable(name, target, sizeof(*target));
+  }
   template<class T>
-  T read_variable(const char *name) const
+  Remote<T> read_variable(const char *name) const
   {
-    static_assert(std::is_trivial<T>::value, "Cannot read a non-trivial type");
-    T res;
-    read_variable(name, &res, sizeof(T));
+    Remote<T> res;
+    read_variable(name, res.getBuffer(), sizeof(T));
     return res;
   }
+
   std::string read_string(RemotePtr<char> address) const;
   std::string read_string(RemotePtr<char> address, std::size_t len) const
   {
index 23d0372..5c11ddc 100644 (file)
@@ -7,11 +7,76 @@
 #ifndef SIMGRID_MC_REMOTE_PTR_HPP
 #define SIMGRID_MC_REMOTE_PTR_HPP
 
+#include <cstddef>
 #include <cstdint>
+#include <cstring>
+
+#include <stdexcept>
+#include <type_traits>
 
 namespace simgrid {
 namespace mc {
 
+template<class M, class T, class Enable = void>
+struct pointer_to_data_member {};
+template<class M, class T>
+struct pointer_to_data_member<M,T,typename std::enable_if< std::is_union<M>::value || std::is_class<M>::value >::type> {
+  typedef T M::* type;
+};
+
+template<class M, class T>
+using pointer_to_data_member_t = typename pointer_to_data_member<M,T>::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<T>;
+ *
+ *  * 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<class T>
+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<T>::value, "Cannot convert non trivial type");
+    return buffer;
+  }
+  void clear()
+  {
+    std::memset(static_cast<void*>(&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<T*> 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
   {
index 09571a1..0c6b839 100644 (file)
@@ -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<simgrid::mc::SimixProcessInformation>& target, xbt_swag_t remote_swag)
+  std::vector<simgrid::mc::SimixProcessInformation>& target,
+  simgrid::mc::RemotePtr<s_xbt_swag_t> 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<simgrid::simix::Global>,
+      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<simgrid::simix::Global> simix_global_p =
+    this->read_variable<simgrid::simix::Global*>("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<simgrid::simix::Global> simix_global =
+    this->read<simgrid::simix::Global>(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;
 }