Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
mc: create RegionSparse, RegionDense and RegionPrivatized (WIP)
[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   explicit 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 protected:
101   RegionType region_type_                      = UnknownRegion;
102   StorageType storage_type_                    = StorageType::NoData;
103   simgrid::mc::ObjectInformation* object_info_ = nullptr;
104
105   /** @brief  Virtual address of the region in the simulated process */
106   void* start_addr_ = nullptr;
107
108   /** @brief Size of the data region in bytes */
109   std::size_t size_ = 0;
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_ = nullptr;
121
122   Buffer flat_data_;
123   ChunkedData page_numbers_;
124   std::vector<std::unique_ptr<RegionSnapshot>> privatized_regions_;
125
126 public:
127   RegionSnapshot() {}
128   RegionSnapshot(RegionType type, void* start_addr, void* permanent_addr, size_t size)
129       : region_type_(type)
130       , start_addr_(start_addr)
131       , size_(size)
132       , permanent_addr_(permanent_addr)
133   {
134   }
135   ~RegionSnapshot()                     = default;
136   RegionSnapshot(RegionSnapshot const&) = delete;
137   RegionSnapshot& operator=(RegionSnapshot const&) = delete;
138   RegionSnapshot(RegionSnapshot&& that)
139       : region_type_(that.region_type_)
140       , storage_type_(that.storage_type_)
141       , object_info_(that.object_info_)
142       , start_addr_(that.start_addr_)
143       , size_(that.size_)
144       , permanent_addr_(that.permanent_addr_)
145       , flat_data_(std::move(that.flat_data_))
146       , page_numbers_(std::move(that.page_numbers_))
147       , privatized_regions_(std::move(that.privatized_regions_))
148   {
149     that.clear();
150   }
151   RegionSnapshot& operator=(RegionSnapshot&& that)
152   {
153     region_type_        = that.region_type_;
154     storage_type_       = that.storage_type_;
155     object_info_        = that.object_info_;
156     start_addr_         = that.start_addr_;
157     size_               = that.size_;
158     permanent_addr_     = that.permanent_addr_;
159     flat_data_          = std::move(that.flat_data_);
160     page_numbers_       = std::move(that.page_numbers_);
161     privatized_regions_ = std::move(that.privatized_regions_);
162     that.clear();
163     return *this;
164   }
165
166   // Data
167
168   void clear()
169   {
170     region_type_  = UnknownRegion;
171     storage_type_ = StorageType::NoData;
172     privatized_regions_.clear();
173     page_numbers_.clear();
174     flat_data_.clear();
175     object_info_    = nullptr;
176     start_addr_     = nullptr;
177     size_           = 0;
178     permanent_addr_ = nullptr;
179   }
180
181   void clear_data()
182   {
183     storage_type_ = StorageType::NoData;
184     flat_data_.clear();
185     page_numbers_.clear();
186     privatized_regions_.clear();
187   }
188
189   const Buffer& flat_data() const { return flat_data_; }
190   Buffer& flat_data() { return flat_data_; }
191
192   ChunkedData const& page_data() const { return page_numbers_; }
193
194   std::vector<std::unique_ptr<RegionSnapshot>> const& privatized_data() const { return privatized_regions_; }
195   std::vector<std::unique_ptr<RegionSnapshot>>& privatized_data() { return privatized_regions_; }
196
197   simgrid::mc::ObjectInformation* object_info() const { return object_info_; }
198   void object_info(simgrid::mc::ObjectInformation* info) { object_info_ = info; }
199
200   // Other getters
201
202   RemotePtr<void> start() const { return remote(start_addr_); }
203   RemotePtr<void> end() const { return remote((char*)start_addr_ + size_); }
204   RemotePtr<void> permanent_address() const { return remote(permanent_addr_); }
205   std::size_t size() const { return size_; }
206   StorageType storage_type() const { return storage_type_; }
207   RegionType region_type() const { return region_type_; }
208
209   bool contain(RemotePtr<void> p) const { return p >= start() && p < end(); }
210 };
211
212 class RegionDense : public RegionSnapshot {
213 public:
214   RegionDense(RegionType type, void* start_addr, void* data_addr, std::size_t size);
215 };
216 class RegionSparse : public RegionSnapshot {
217 public:
218   RegionSparse(RegionType type, void* start_addr, void* data_addr, std::size_t size);
219 };
220 class RegionPrivatized : public RegionSnapshot {
221 public:
222   RegionPrivatized(RegionType type, void* start_addr, void* data_addr, std::size_t size);
223 };
224
225 RegionSnapshot* region(RegionType type, void* start_addr, void* data_addr, std::size_t size);
226
227 } // namespace mc
228 } // namespace simgrid
229
230 #endif