1 /* Copyright (c) 2007-2019. The SimGrid Team. All rights reserved. */
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. */
6 #ifndef SIMGRID_MC_REGION_SNAPSHOT_HPP
7 #define SIMGRID_MC_REGION_SNAPSHOT_HPP
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"
25 enum class RegionType { Unknown = 0, Heap = 1, Data = 2 };
27 enum class StorageType { NoData = 0, Flat = 1, Chunked = 2, Privatized = 3 };
31 void* data_ = nullptr;
34 explicit Buffer(std::size_t size) : size_(size) { data_ = ::operator new(size_); }
36 Buffer(void* data, std::size_t size) : data_(data), size_(size) {}
42 ::operator delete(data_);
47 ~Buffer() noexcept { clear(); }
49 static Buffer malloc(std::size_t size) { return Buffer(size); }
52 Buffer(Buffer const& buffer) = delete;
53 Buffer& operator=(Buffer const& buffer) = delete;
56 Buffer(Buffer&& that) noexcept : data_(that.data_), size_(that.size_)
61 Buffer& operator=(Buffer&& that) noexcept
71 void* get() { return data_; }
72 const void* get() const { return data_; }
73 std::size_t size() const { return size_; }
76 /** A copy/snapshot of a given memory region
78 * Different types of region snapshot storage types exist:
80 * * flat/dense snapshots are a simple copy of the region;
82 * * sparse/per-page snapshots are snaapshots which shared
85 * * privatized (SMPI global variable privatization).
87 * This is handled with a variant based approach:
89 * * `storage_type` identified the type of storage;
91 * * an anonymous enum is used to distinguish the relevant types for
94 class RegionSnapshot {
96 static const RegionType UnknownRegion = RegionType::Unknown;
97 static const RegionType HeapRegion = RegionType::Heap;
98 static const RegionType DataRegion = RegionType::Data;
101 RegionType region_type_ = UnknownRegion;
102 StorageType storage_type_ = StorageType::NoData;
103 simgrid::mc::ObjectInformation* object_info_ = nullptr;
105 /** @brief Virtual address of the region in the simulated process */
106 void* start_addr_ = nullptr;
108 /** @brief Size of the data region in bytes */
109 std::size_t size_ = 0;
111 /** @brief Permanent virtual address of the region
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.
120 void* permanent_addr_ = nullptr;
123 ChunkedData page_numbers_;
124 std::vector<RegionSnapshot> privatized_regions_;
128 RegionSnapshot(RegionType type, void* start_addr, void* permanent_addr, size_t size)
130 , start_addr_(start_addr)
132 , permanent_addr_(permanent_addr)
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_)
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_))
151 RegionSnapshot& operator=(RegionSnapshot&& that)
153 region_type_ = that.region_type_;
154 storage_type_ = that.storage_type_;
155 object_info_ = that.object_info_;
156 start_addr_ = that.start_addr_;
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_);
170 region_type_ = UnknownRegion;
171 storage_type_ = StorageType::NoData;
172 privatized_regions_.clear();
173 page_numbers_.clear();
175 object_info_ = nullptr;
176 start_addr_ = nullptr;
178 permanent_addr_ = nullptr;
183 storage_type_ = StorageType::NoData;
185 page_numbers_.clear();
186 privatized_regions_.clear();
189 void flat_data(Buffer data)
191 storage_type_ = StorageType::Flat;
192 flat_data_ = std::move(data);
193 page_numbers_.clear();
194 privatized_regions_.clear();
196 const Buffer& flat_data() const { return flat_data_; }
197 Buffer& flat_data() { return flat_data_; }
199 void page_data(ChunkedData&& page_data)
201 storage_type_ = StorageType::Chunked;
203 page_numbers_ = std::move(page_data);
204 privatized_regions_.clear();
206 ChunkedData const& page_data() const { return page_numbers_; }
208 void privatized_data(std::vector<RegionSnapshot> data)
210 storage_type_ = StorageType::Privatized;
212 page_numbers_.clear();
213 privatized_regions_ = std::move(data);
215 std::vector<RegionSnapshot> const& privatized_data() const { return privatized_regions_; }
216 std::vector<RegionSnapshot>& privatized_data() { return privatized_regions_; }
218 simgrid::mc::ObjectInformation* object_info() const { return object_info_; }
219 void object_info(simgrid::mc::ObjectInformation* info) { object_info_ = info; }
223 RemotePtr<void> start() const { return remote(start_addr_); }
224 RemotePtr<void> end() const { return remote((char*)start_addr_ + size_); }
225 RemotePtr<void> permanent_address() const { return remote(permanent_addr_); }
226 std::size_t size() const { return size_; }
227 StorageType storage_type() const { return storage_type_; }
228 RegionType region_type() const { return region_type_; }
230 bool contain(RemotePtr<void> p) const { return p >= start() && p < end(); }
233 RegionSnapshot privatized_region(RegionType region_type, void* start_addr, void* permanent_addr, std::size_t size);
234 RegionSnapshot dense_region(RegionType type, void* start_addr, void* data_addr, std::size_t size);
235 simgrid::mc::RegionSnapshot sparse_region(RegionType type, void* start_addr, void* data_addr, std::size_t size);
236 simgrid::mc::RegionSnapshot region(RegionType type, void* start_addr, void* data_addr, std::size_t size);
239 } // namespace simgrid