Logo AND Algorithmique Numérique Distribuée

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