Logo AND Algorithmique Numérique Distribuée

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