Logo AND Algorithmique Numérique Distribuée

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