Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
mc: Also remove the process_index
[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 "src/mc/remote/RemotePtr.hpp"
10 #include "src/mc/sosp/ChunkedData.hpp"
11
12 #include <memory>
13 #include <vector>
14
15 namespace simgrid {
16 namespace mc {
17
18 enum class RegionType { Unknown = 0, Heap = 1, Data = 2 };
19
20 enum class StorageType { NoData = 0, Flat = 1, Chunked = 2 };
21
22 class Buffer {
23 private:
24   void* data_ = nullptr;
25   std::size_t size_;
26
27   explicit Buffer(std::size_t size) : size_(size) { data_ = ::operator new(size_); }
28
29   Buffer(void* data, std::size_t size) : data_(data), size_(size) {}
30
31 public:
32   Buffer() = default;
33   void clear() noexcept
34   {
35     ::operator delete(data_);
36     data_ = nullptr;
37     size_ = 0;
38   }
39
40   ~Buffer() noexcept { clear(); }
41
42   static Buffer malloc(std::size_t size) { return Buffer(size); }
43
44   // No copy
45   Buffer(Buffer const& buffer) = delete;
46   Buffer& operator=(Buffer const& buffer) = delete;
47
48   // Move
49   Buffer(Buffer&& that) noexcept : data_(that.data_), size_(that.size_)
50   {
51     that.data_ = nullptr;
52     that.size_ = 0;
53   }
54   Buffer& operator=(Buffer&& that) noexcept
55   {
56     clear();
57     data_      = that.data_;
58     size_      = that.size_;
59     that.data_ = nullptr;
60     that.size_ = 0;
61     return *this;
62   }
63
64   void* get() { return data_; }
65   const void* get() const { return data_; }
66   std::size_t size() const { return size_; }
67 };
68
69 /** A copy/snapshot of a given memory region
70  *
71  *  Different types of region snapshot storage types exist:
72  *
73  *  * flat/dense snapshots are a simple copy of the region;
74  *
75  *  * sparse/per-page snapshots are snaapshots which shared
76  *    identical pages.
77  *
78  *  * privatized (SMPI global variable privatization).
79  *
80  *  This is handled with a variant based approach:
81  *
82  *  * `storage_type` identified the type of storage;
83  *
84  *  * an anonymous enum is used to distinguish the relevant types for
85  *    each type.
86  */
87 class RegionSnapshot {
88 public:
89   static const RegionType UnknownRegion = RegionType::Unknown;
90   static const RegionType HeapRegion    = RegionType::Heap;
91   static const RegionType DataRegion    = RegionType::Data;
92
93 protected:
94   RegionType region_type_                      = UnknownRegion;
95   StorageType storage_type_                    = StorageType::NoData;
96   simgrid::mc::ObjectInformation* object_info_ = nullptr;
97
98   /** @brief  Virtual address of the region in the simulated process */
99   void* start_addr_ = nullptr;
100
101   /** @brief Size of the data region in bytes */
102   std::size_t size_ = 0;
103
104   /** @brief Permanent virtual address of the region
105    *
106    * This is usually the same address as the simuilated process address.
107    * However, when using SMPI privatization of global variables,
108    * each SMPI process has its own set of global variables stored
109    * at a different virtual address. The scheduler maps those region
110    * on the region of the global variables.
111    *
112    * */
113   void* permanent_addr_ = nullptr;
114
115   Buffer flat_data_;
116   ChunkedData page_numbers_;
117
118 public:
119   RegionSnapshot() {}
120   RegionSnapshot(RegionType type, void* start_addr, void* permanent_addr, size_t size)
121       : region_type_(type)
122       , start_addr_(start_addr)
123       , size_(size)
124       , permanent_addr_(permanent_addr)
125   {
126   }
127   ~RegionSnapshot()                     = default;
128   RegionSnapshot(RegionSnapshot const&) = delete;
129   RegionSnapshot& operator=(RegionSnapshot const&) = delete;
130   RegionSnapshot(RegionSnapshot&& that)
131       : region_type_(that.region_type_)
132       , storage_type_(that.storage_type_)
133       , object_info_(that.object_info_)
134       , start_addr_(that.start_addr_)
135       , size_(that.size_)
136       , permanent_addr_(that.permanent_addr_)
137       , flat_data_(std::move(that.flat_data_))
138       , page_numbers_(std::move(that.page_numbers_))
139   {
140     that.clear();
141   }
142   RegionSnapshot& operator=(RegionSnapshot&& that)
143   {
144     region_type_        = that.region_type_;
145     storage_type_       = that.storage_type_;
146     object_info_        = that.object_info_;
147     start_addr_         = that.start_addr_;
148     size_               = that.size_;
149     permanent_addr_     = that.permanent_addr_;
150     flat_data_          = std::move(that.flat_data_);
151     page_numbers_       = std::move(that.page_numbers_);
152     that.clear();
153     return *this;
154   }
155
156   // Data
157
158   void clear()
159   {
160     region_type_  = UnknownRegion;
161     storage_type_ = StorageType::NoData;
162     page_numbers_.clear();
163     flat_data_.clear();
164     object_info_    = nullptr;
165     start_addr_     = nullptr;
166     size_           = 0;
167     permanent_addr_ = nullptr;
168   }
169
170   void clear_data()
171   {
172     storage_type_ = StorageType::NoData;
173     flat_data_.clear();
174     page_numbers_.clear();
175   }
176
177   const Buffer& flat_data() const { return flat_data_; }
178   Buffer& flat_data() { return flat_data_; }
179
180   ChunkedData const& page_data() const { return page_numbers_; }
181
182   simgrid::mc::ObjectInformation* object_info() const { return object_info_; }
183   void object_info(simgrid::mc::ObjectInformation* info) { object_info_ = info; }
184
185   // Other getters
186
187   RemotePtr<void> start() const { return remote(start_addr_); }
188   RemotePtr<void> end() const { return remote((char*)start_addr_ + size_); }
189   RemotePtr<void> permanent_address() const { return remote(permanent_addr_); }
190   std::size_t size() const { return size_; }
191   StorageType storage_type() const { return storage_type_; }
192   RegionType region_type() const { return region_type_; }
193
194   bool contain(RemotePtr<void> p) const { return p >= start() && p < end(); }
195
196   /** @brief Restore a region from a snapshot */
197   void restore();
198 };
199
200 class RegionDense : public RegionSnapshot {
201 public:
202   RegionDense(RegionType type, void* start_addr, void* data_addr, std::size_t size);
203 };
204 class RegionSparse : public RegionSnapshot {
205 public:
206   RegionSparse(RegionType type, void* start_addr, void* data_addr, std::size_t size);
207 };
208
209 RegionSnapshot* region(RegionType type, void* start_addr, void* data_addr, std::size_t size);
210
211 } // namespace mc
212 } // namespace simgrid
213
214 #endif