Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
enable MPICH3 tests on travis to get the associated coverage on sonar
[simgrid.git] / src / mc / RegionSnapshot.hpp
1 /* Copyright (c) 2007-2015. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #ifndef SIMGRID_MC_REGION_SNAPSHOT_HPP
8 #define SIMGRID_MC_REGION_SNAPSHOT_HPP
9
10 #include <cstddef>
11 #include <utility>
12
13 #include <memory>
14 #include <vector>
15
16 #include "xbt/base.h"
17
18 #include "src/mc/AddressSpace.hpp"
19 #include "src/mc/ChunkedData.hpp"
20 #include "src/mc/PageStore.hpp"
21 #include "src/mc/remote/RemotePtr.hpp"
22
23 namespace simgrid {
24 namespace mc {
25
26 enum class RegionType {
27   Unknown = 0,
28   Heap = 1,
29   Data = 2
30 };
31
32 enum class StorageType {
33   NoData = 0,
34   Flat = 1,
35   Chunked = 2,
36   Privatized = 3
37 };
38
39 class Buffer {
40 private:
41   enum class Type {
42     Malloc,
43     Mmap
44   };
45   void* data_ = nullptr;
46   std::size_t size_;
47   Type type_ = Type::Malloc;
48 private:
49   Buffer(std::size_t size, Type type = Type::Malloc);
50   Buffer(void* data, std::size_t size, Type type = Type::Malloc) :
51     data_(data), size_(size), type_(type) {}
52 public:
53   Buffer() = default;
54   void clear() noexcept;
55   ~Buffer() noexcept { clear(); }
56
57   static Buffer malloc(std::size_t size)
58   {
59     return Buffer(size, Type::Malloc);
60   }
61   static Buffer mmap(std::size_t size)
62   {
63     return Buffer(size, Type::Mmap);
64   }
65
66   // No copy
67   Buffer(Buffer const& buffer) = delete;
68   Buffer& operator=(Buffer const& buffer) = delete;
69
70   // Move
71   Buffer(Buffer&& that) noexcept
72     : data_(that.data_), size_(that.size_), type_(that.type_)
73   {
74     that.data_ = nullptr;
75     that.size_ = 0;
76     that.type_ = Type::Malloc;
77   }
78   Buffer& operator=(Buffer&& that) noexcept
79   {
80     clear();
81     data_ = that.data_;
82     size_ = that.size_;
83     type_ = that.type_;
84     that.data_ = nullptr;
85     that.size_ = 0;
86     that.type_ = Type::Malloc;
87     return *this;
88   }
89
90   void* get()              { return data_; }
91   const void* get()  const { return data_; }
92   std::size_t size() const { return size_; }
93 };
94
95 /** A copy/snapshot of a given memory region
96  *
97  *  Different types of region snapshot storage types exist:
98  *
99  *  * flat/dense snapshots are a simple copy of the region;
100  *
101  *  * sparse/per-page snapshots are snaapshots which shared
102  *    identical pages.
103  *
104  *  * privatized (SMPI global variable privatization).
105  *
106  *  This is handled with a variant based approach:
107  *
108  *  * `storage_type` identified the type of storage;
109  *
110  *  * an anonymous enum is used to distinguish the relevant types for
111  *    each type.
112  */
113 class RegionSnapshot {
114 public:
115   static const RegionType UnknownRegion = RegionType::Unknown;
116   static const RegionType HeapRegion = RegionType::Heap;
117   static const RegionType DataRegion = RegionType::Data;
118 private:
119   RegionType region_type_;
120   StorageType storage_type_;
121   simgrid::mc::ObjectInformation* object_info_;
122
123   /** @brief  Virtual address of the region in the simulated process */
124   void *start_addr_;
125
126   /** @brief Size of the data region in bytes */
127   std::size_t size_;
128
129   /** @brief Permanent virtual address of the region
130    *
131    * This is usually the same address as the simuilated process address.
132    * However, when using SMPI privatization of global variables,
133    * each SMPI process has its own set of global variables stored
134    * at a different virtual address. The scheduler maps those region
135    * on the region of the global variables.
136    *
137    * */
138   void *permanent_addr_;
139
140   Buffer flat_data_;
141   ChunkedData page_numbers_;
142   std::vector<RegionSnapshot> privatized_regions_;
143 public:
144   RegionSnapshot() :
145     region_type_(UnknownRegion),
146     storage_type_(StorageType::NoData),
147     object_info_(nullptr),
148     start_addr_(nullptr),
149     size_(0),
150     permanent_addr_(nullptr)
151   {}
152   RegionSnapshot(RegionType type, void *start_addr, void* permanent_addr, size_t size) :
153     region_type_(type),
154     storage_type_(StorageType::NoData),
155     object_info_(nullptr),
156     start_addr_(start_addr),
157     size_(size),
158     permanent_addr_(permanent_addr)
159   {}
160   ~RegionSnapshot()                     = default;
161   RegionSnapshot(RegionSnapshot const&) = default;
162   RegionSnapshot& operator=(RegionSnapshot const&) = default;
163   RegionSnapshot(RegionSnapshot&& that)
164   {
165     region_type_ = that.region_type_;
166     storage_type_ = that.storage_type_;
167     object_info_ = that.object_info_;
168     start_addr_ = that.start_addr_;
169     size_ = that.size_;
170     permanent_addr_ = that.permanent_addr_;
171     flat_data_ = std::move(that.flat_data_);
172     page_numbers_ = std::move(that.page_numbers_);
173     privatized_regions_ = std::move(that.privatized_regions_);
174     that.clear();
175   }
176   RegionSnapshot& operator=(RegionSnapshot&& that)
177   {
178     region_type_ = that.region_type_;
179     storage_type_ = that.storage_type_;
180     object_info_ = that.object_info_;
181     start_addr_ = that.start_addr_;
182     size_ = that.size_;
183     permanent_addr_ = that.permanent_addr_;
184     flat_data_ = std::move(that.flat_data_);
185     page_numbers_ = std::move(that.page_numbers_);
186     privatized_regions_ = std::move(that.privatized_regions_);
187     that.clear();
188     return *this;
189   }
190
191   // Data
192
193   void clear()
194   {
195     region_type_ = UnknownRegion;
196     storage_type_ = StorageType::NoData;
197     privatized_regions_.clear();
198     page_numbers_.clear();
199     flat_data_.clear();
200     object_info_ = nullptr;
201     start_addr_ = nullptr;
202     size_ = 0;
203     permanent_addr_ = nullptr;
204   }
205
206   void clear_data()
207   {
208     storage_type_ = StorageType::NoData;
209     flat_data_.clear();
210     page_numbers_.clear();
211     privatized_regions_.clear();
212   }
213
214   void flat_data(Buffer data)
215   {
216     storage_type_ = StorageType::Flat;
217     flat_data_ = std::move(data);
218     page_numbers_.clear();
219     privatized_regions_.clear();
220   }
221   const Buffer& flat_data() const { return flat_data_; }
222   Buffer& flat_data()             { return flat_data_; }
223
224   void page_data(ChunkedData page_data)
225   {
226     storage_type_ = StorageType::Chunked;
227     flat_data_.clear();
228     page_numbers_ = std::move(page_data);
229     privatized_regions_.clear();
230   }
231   ChunkedData const& page_data() const { return page_numbers_; }
232
233   void privatized_data(std::vector<RegionSnapshot> data)
234   {
235     storage_type_ = StorageType::Privatized;
236     flat_data_.clear();
237     page_numbers_.clear();
238     privatized_regions_ = std::move(data);
239   }
240   std::vector<RegionSnapshot> const& privatized_data() const
241   {
242     return privatized_regions_;
243   }
244   std::vector<RegionSnapshot>& privatized_data()
245   {
246     return privatized_regions_;
247   }
248
249   simgrid::mc::ObjectInformation* object_info() const { return object_info_; }
250   void object_info(simgrid::mc::ObjectInformation* info) { object_info_ = info; }
251
252   // Other getters
253
254   RemotePtr<void> start() const { return remote(start_addr_); }
255   RemotePtr<void> end() const { return remote((char*)start_addr_ + size_); }
256   RemotePtr<void> permanent_address() const { return remote(permanent_addr_); }
257   std::size_t size() const { return size_; }
258   StorageType storage_type() const { return storage_type_; }
259   RegionType region_type() const { return region_type_; }
260
261   bool contain(RemotePtr<void> p) const
262   {
263     return p >= start() && p < end();
264   }
265 };
266
267 RegionSnapshot privatized_region(
268     RegionType region_type, void *start_addr, void* permanent_addr,
269     std::size_t size);
270 RegionSnapshot dense_region(
271   RegionType type, void *start_addr, void* data_addr, std::size_t size);
272 simgrid::mc::RegionSnapshot sparse_region(
273   RegionType type, void *start_addr, void* data_addr, std::size_t size);
274 simgrid::mc::RegionSnapshot region(
275   RegionType type, void *start_addr, void* data_addr, std::size_t size);
276
277 }
278 }
279
280 typedef class simgrid::mc::RegionSnapshot s_mc_mem_region_t;
281 typedef s_mc_mem_region_t* mc_mem_region_t;
282 #endif