Logo AND Algorithmique Numérique Distribuée

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