Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
0c85f22eb3f302f8d163e9dc2c5a33e7952627d7
[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 #include <cstddef>
8 #include <utility>
9
10 #include "PageStore.hpp"
11 #include "AddressSpace.hpp"
12
13 #ifndef SIMGRID_MC_REGION_SNAPSHOT_HPP
14 #define SIMGRID_MC_REGION_SNAPSHOT_HPP
15
16 typedef enum e_mc_region_type_t {
17   MC_REGION_TYPE_UNKNOWN = 0,
18   MC_REGION_TYPE_HEAP = 1,
19   MC_REGION_TYPE_DATA = 2
20 } mc_region_type_t;
21
22 // TODO, use OO instead of this
23 typedef enum e_mc_region_storage_type_t {
24   MC_REGION_STORAGE_TYPE_NONE = 0,
25   MC_REGION_STORAGE_TYPE_FLAT = 1,
26   MC_REGION_STORAGE_TYPE_CHUNKED = 2,
27   MC_REGION_STORAGE_TYPE_PRIVATIZED = 3
28 } mc_region_storage_type_t;
29
30 namespace simgrid {
31 namespace mc {
32
33 class PerPageCopy {
34   PageStore* store_;
35   std::vector<std::size_t> pagenos_;
36 public:
37   PerPageCopy() : store_(nullptr) {}
38   PerPageCopy(PerPageCopy const& that)
39   {
40     store_ = that.store_;
41     pagenos_ = that.pagenos_;
42     for (std::size_t pageno : pagenos_)
43       store_->ref_page(pageno);
44   }
45   void clear()
46   {
47     for (std::size_t pageno : pagenos_)
48       store_->unref_page(pageno);
49     pagenos_.clear();
50   }
51   ~PerPageCopy() {
52     clear();
53   }
54
55   PerPageCopy(PerPageCopy&& that)
56   {
57     store_ = that.store_;
58     that.store_ = nullptr;
59     pagenos_ = std::move(that.pagenos_);
60     that.pagenos_.clear();
61   }
62   PerPageCopy& operator=(PerPageCopy const& that)
63   {
64     this->clear();
65     store_ = that.store_;
66     pagenos_ = that.pagenos_;
67     for (std::size_t pageno : pagenos_)
68       store_->ref_page(pageno);
69     return *this;
70   }
71   PerPageCopy& operator=(PerPageCopy && that)
72   {
73     this->clear();
74     store_ = that.store_;
75     that.store_ = nullptr;
76     pagenos_ = std::move(that.pagenos_);
77     that.pagenos_.clear();
78     return *this;
79   }
80
81   std::size_t page_count() const
82   {
83     return pagenos_.size();
84   }
85
86   std::size_t pageno(std::size_t i) const
87   {
88     return pagenos_[i];
89   }
90
91   const void* page(std::size_t i) const
92   {
93     return store_->get_page(pagenos_[i]);
94   }
95
96   PerPageCopy(PageStore& store, AddressSpace& as,
97     remote_ptr<void> addr, std::size_t page_count);
98 };
99
100 /** @brief Copy/snapshot of a given memory region
101  *
102  *  Different types of region snapshot storage types exist:
103  *  <ul>
104  *    <li>flat/dense snapshots are a simple copy of the region;</li>
105  *    <li>sparse/per-page snapshots are snaapshots which shared
106  *    identical pages.</li>
107  *    <li>privatized (SMPI global variable privatisation).
108  *  </ul>
109  *
110  *  This is handled with a variant based approch:
111  *
112  *    * `storage_type` identified the type of storage;
113  *    * an anonymous enum is used to distinguish the relevant types for
114  *      each type.
115  */
116 class RegionSnapshot {
117 private:
118   mc_region_type_t region_type_;
119   mc_region_storage_type_t storage_type_;
120   mc_object_info_t object_info_;
121
122   /** @brief  Virtual address of the region in the simulated process */
123   void *start_addr_;
124
125   /** @brief Size of the data region in bytes */
126   size_t size_;
127
128   /** @brief Permanent virtual address of the region
129    *
130    * This is usually the same address as the simuilated process address.
131    * However, when using SMPI privatization of global variables,
132    * each SMPI process has its own set of global variables stored
133    * at a different virtual address. The scheduler maps those region
134    * on the region of the global variables.
135    *
136    * */
137   void *permanent_addr_;
138
139   std::vector<char> flat_data_;
140   PerPageCopy page_numbers_;
141   std::vector<RegionSnapshot> privatized_regions_;
142 public:
143   RegionSnapshot() :
144     region_type_(MC_REGION_TYPE_UNKNOWN),
145     storage_type_(MC_REGION_STORAGE_TYPE_NONE),
146     object_info_(nullptr),
147     start_addr_(nullptr),
148     size_(0),
149     permanent_addr_(nullptr)
150   {}
151   RegionSnapshot(mc_region_type_t type, void *start_addr, void* permanent_addr, size_t size) :
152     region_type_(type),
153     storage_type_(MC_REGION_STORAGE_TYPE_NONE),
154     object_info_(nullptr),
155     start_addr_(start_addr),
156     size_(size),
157     permanent_addr_(permanent_addr)
158   {}
159   ~RegionSnapshot() {}
160   RegionSnapshot(RegionSnapshot const&) = default;
161   RegionSnapshot& operator=(RegionSnapshot const&) = default;
162   RegionSnapshot(RegionSnapshot&& that)
163   {
164     region_type_ = that.region_type_;
165     storage_type_ = that.storage_type_;
166     object_info_ = that.object_info_;
167     start_addr_ = that.start_addr_;
168     size_ = that.size_;
169     permanent_addr_ = that.permanent_addr_;
170     flat_data_ = std::move(that.flat_data_);
171     page_numbers_ = std::move(that.page_numbers_);
172     privatized_regions_ = std::move(that.privatized_regions_);
173     that.clear();
174   }
175   RegionSnapshot& operator=(RegionSnapshot&& that)
176   {
177     region_type_ = that.region_type_;
178     storage_type_ = that.storage_type_;
179     object_info_ = that.object_info_;
180     start_addr_ = that.start_addr_;
181     size_ = that.size_;
182     permanent_addr_ = that.permanent_addr_;
183     flat_data_ = std::move(that.flat_data_);
184     page_numbers_ = std::move(that.page_numbers_);
185     privatized_regions_ = std::move(that.privatized_regions_);
186     that.clear();
187     return *this;
188   }
189
190   // Data
191
192   void clear()
193   {
194     region_type_ = MC_REGION_TYPE_UNKNOWN;
195     storage_type_ = MC_REGION_STORAGE_TYPE_NONE;
196     privatized_regions_.clear();
197     page_numbers_.clear();
198     flat_data_.clear();
199     object_info_ = nullptr;
200     start_addr_ = nullptr;
201     size_ = 0;
202     permanent_addr_ = nullptr;
203   }
204
205   void clear_data()
206   {
207     storage_type_ = MC_REGION_STORAGE_TYPE_NONE;
208     flat_data_.clear();
209     page_numbers_.clear();
210     privatized_regions_.clear();
211   }
212   
213   void flat_data(std::vector<char> data)
214   {
215     storage_type_ = MC_REGION_STORAGE_TYPE_FLAT;
216     flat_data_ = std::move(data);
217     page_numbers_.clear();
218     privatized_regions_.clear();
219   }
220   std::vector<char> const& flat_data() const { return flat_data_; }
221
222   void page_data(PerPageCopy page_data)
223   {
224     storage_type_ = MC_REGION_STORAGE_TYPE_CHUNKED;
225     flat_data_.clear();
226     page_numbers_ = std::move(page_data);
227     privatized_regions_.clear();
228   }
229   PerPageCopy const& page_data() const { return page_numbers_; }
230
231   void privatized_data(std::vector<RegionSnapshot> data)
232   {
233     storage_type_ = MC_REGION_STORAGE_TYPE_PRIVATIZED;
234     flat_data_.clear();
235     page_numbers_.clear();
236     privatized_regions_ = std::move(data);
237   }
238   std::vector<RegionSnapshot> const& privatized_data() const
239   {
240     return privatized_regions_;
241   }
242   std::vector<RegionSnapshot>& privatized_data()
243   {
244     return privatized_regions_;
245   }
246
247   mc_object_info_t object_info() const { return object_info_; }
248   void object_info(mc_object_info_t info) { object_info_ = info; }
249
250   // Other getters
251
252   remote_ptr<void> start() const { return remote(start_addr_); }
253   remote_ptr<void> end() const { return remote((char*)start_addr_ + size_); }
254   remote_ptr<void> permanent_address() const { return remote(permanent_addr_); }
255   std::size_t size() const { return size_; }
256   mc_region_storage_type_t storage_type() const { return storage_type_; }
257   mc_region_type_t region_type() const { return region_type_; }
258
259   bool contain(remote_ptr<void> p) const
260   {
261     return p >= start() && p < end();
262   }
263 };
264
265 simgrid::mc::RegionSnapshot privatized_region(
266   mc_region_type_t type, void *start_addr, void* data_addr, size_t size);
267 simgrid::mc::RegionSnapshot dense_region(
268   mc_region_type_t type, void *start_addr, void* data_addr, size_t size);
269 simgrid::mc::RegionSnapshot sparse_region(
270   mc_region_type_t type, void *start_addr, void* data_addr, size_t size);
271 simgrid::mc::RegionSnapshot region(
272   mc_region_type_t type, void *start_addr, void* data_addr, size_t size);
273   
274 }
275 }
276
277 typedef class simgrid::mc::RegionSnapshot s_mc_mem_region_t, *mc_mem_region_t;
278
279 #endif