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