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
9 #include "src/mc/remote/RemotePtr.hpp"
10 #include "src/mc/sosp/ChunkedData.hpp"
18 enum class RegionType { Unknown = 0, Heap = 1, Data = 2 };
20 enum class StorageType { NoData = 0, Flat = 1, Chunked = 2 };
24 void* data_ = nullptr;
27 explicit Buffer(std::size_t size) : size_(size) { data_ = ::operator new(size_); }
29 Buffer(void* data, std::size_t size) : data_(data), size_(size) {}
35 ::operator delete(data_);
40 ~Buffer() noexcept { clear(); }
42 static Buffer malloc(std::size_t size) { return Buffer(size); }
45 Buffer(Buffer const& buffer) = delete;
46 Buffer& operator=(Buffer const& buffer) = delete;
49 Buffer(Buffer&& that) noexcept : data_(that.data_), size_(that.size_)
54 Buffer& operator=(Buffer&& that) noexcept
64 void* get() { return data_; }
65 const void* get() const { return data_; }
66 std::size_t size() const { return size_; }
69 /** A copy/snapshot of a given memory region
71 * Different types of region snapshot storage types exist:
73 * * flat/dense snapshots are a simple copy of the region;
75 * * sparse/per-page snapshots are snaapshots which shared
78 * * privatized (SMPI global variable privatization).
80 * This is handled with a variant based approach:
82 * * `storage_type` identified the type of storage;
84 * * an anonymous enum is used to distinguish the relevant types for
87 class RegionSnapshot {
89 static const RegionType UnknownRegion = RegionType::Unknown;
90 static const RegionType HeapRegion = RegionType::Heap;
91 static const RegionType DataRegion = RegionType::Data;
94 RegionType region_type_ = UnknownRegion;
95 StorageType storage_type_ = StorageType::NoData;
96 simgrid::mc::ObjectInformation* object_info_ = nullptr;
98 /** @brief Virtual address of the region in the simulated process */
99 void* start_addr_ = nullptr;
101 /** @brief Size of the data region in bytes */
102 std::size_t size_ = 0;
104 /** @brief Permanent virtual address of the region
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.
113 void* permanent_addr_ = nullptr;
116 ChunkedData page_numbers_;
120 RegionSnapshot(RegionType type, void* start_addr, void* permanent_addr, size_t size)
122 , start_addr_(start_addr)
124 , permanent_addr_(permanent_addr)
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_)
136 , permanent_addr_(that.permanent_addr_)
137 , flat_data_(std::move(that.flat_data_))
138 , page_numbers_(std::move(that.page_numbers_))
142 RegionSnapshot& operator=(RegionSnapshot&& that)
144 region_type_ = that.region_type_;
145 storage_type_ = that.storage_type_;
146 object_info_ = that.object_info_;
147 start_addr_ = that.start_addr_;
149 permanent_addr_ = that.permanent_addr_;
150 flat_data_ = std::move(that.flat_data_);
151 page_numbers_ = std::move(that.page_numbers_);
160 region_type_ = UnknownRegion;
161 storage_type_ = StorageType::NoData;
162 page_numbers_.clear();
164 object_info_ = nullptr;
165 start_addr_ = nullptr;
167 permanent_addr_ = nullptr;
172 storage_type_ = StorageType::NoData;
174 page_numbers_.clear();
177 const Buffer& flat_data() const { return flat_data_; }
178 Buffer& flat_data() { return flat_data_; }
180 ChunkedData const& page_data() const { return page_numbers_; }
182 simgrid::mc::ObjectInformation* object_info() const { return object_info_; }
183 void object_info(simgrid::mc::ObjectInformation* info) { object_info_ = info; }
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_; }
194 bool contain(RemotePtr<void> p) const { return p >= start() && p < end(); }
196 /** @brief Restore a region from a snapshot */
200 class RegionDense : public RegionSnapshot {
202 RegionDense(RegionType type, void* start_addr, void* data_addr, std::size_t size);
204 class RegionSparse : public RegionSnapshot {
206 RegionSparse(RegionType type, void* start_addr, void* data_addr, std::size_t size);
209 RegionSnapshot* region(RegionType type, void* start_addr, void* data_addr, std::size_t size);
212 } // namespace simgrid