18 #ifndef PSTORE_CORE_STORAGE_HPP 19 #define PSTORE_CORE_STORAGE_HPP 39 bool is_valid () const noexcept {
40 if (value ==
nullptr && region ==
nullptr) {
44 auto *
const ptr =
static_cast<std::uint8_t
const *
> (value.get ());
45 auto *
const region_base =
static_cast<std::uint8_t
const *
> (region->data ().get ());
46 auto *
const region_end = region_base + region->size ();
54 using segment_address_table = std::array<sat_entry, sat_elements>;
55 using sat_iterator = segment_address_table::iterator;
56 using file_ptr = std::shared_ptr<file::file_base>;
60 static auto constexpr full_region_size = UINT64_C (1) << 32U;
61 static auto constexpr min_region_size = UINT64_C (1) << 22U;
63 PSTORE_STATIC_ASSERT (full_region_size % min_region_size == 0);
65 using region_container = std::vector<region::memory_mapper_ptr>;
67 template <
typename File>
68 storage (std::shared_ptr<File>
const & file,
69 std::unique_ptr<system_page_size_interface> && page_size,
70 std::unique_ptr<region::factory> && region_factory)
72 , page_size_{std::move (page_size)}
73 , region_factory_{std::move (region_factory)}
74 , regions_{region_factory_->init ()} {}
76 template <
typename File>
77 explicit storage (std::shared_ptr<File>
const & file)
79 , region_factory_{region::get_factory (
80 std::static_pointer_cast<file::file_handle> (file), full_region_size,
82 , regions_{region_factory_->init ()} {}
87 void map_bytes (std::uint64_t new_size);
91 void update_master_pointers (std::size_t old_length);
94 using in_store_pointer = std::uint8_t
const *;
95 using temp_pointer = std::uint8_t *;
98 using in_store_pointer = std::uint8_t *;
99 using temp_pointer = std::uint8_t
const *;
122 template <
typename Traits,
typename Function>
123 void copy (
address addr, std::size_t size,
typename Traits::temp_pointer p,
124 Function copier)
const;
136 bool request_spans_regions (
address const & addr, std::size_t size)
const noexcept;
145 std::shared_ptr<void const>
147 return segment_base_impl (*
this, segment);
149 std::shared_ptr<void>
const & segment_base (address::segment_type
const segment) noexcept {
150 return segment_base_impl (*
this, segment);
155 std::shared_ptr<void const> address_to_pointer (
address const addr)
const noexcept {
156 return address_to_pointer_impl (*
this, addr);
158 std::shared_ptr<void> address_to_pointer (
address const addr) noexcept {
159 return address_to_pointer_impl (*
this, addr);
162 template <
typename T>
163 std::shared_ptr<T const> address_to_pointer (
typed_address<T> addr)
const noexcept {
164 return std::static_pointer_cast<T
const> (address_to_pointer (addr.to_address ()));
166 template <
typename T>
168 return std::static_pointer_cast<T> (address_to_pointer (addr.to_address ()));
174 region_container
const & regions ()
const {
return regions_; }
177 void shrink (std::uint64_t new_size);
180 slice_region_into_segments (std::shared_ptr<memory_mapper_base>
const &
region,
181 sat_iterator segment_it, sat_iterator segment_end);
183 template <
typename Storage,
185 Storage, std::shared_ptr<void>
const &, std::shared_ptr<void const>>::type>
186 static auto segment_base_impl (Storage &
storage,
187 address::segment_type
const segment) noexcept -> ResultType;
189 template <
typename Storage,
191 std::shared_ptr<void const>>::type>
192 static auto address_to_pointer_impl (Storage & storage,
address const addr) noexcept
197 std::unique_ptr<segment_address_table> sat_ = std::make_unique<segment_address_table> ();
201 std::unique_ptr<system_page_size_interface> page_size_ =
202 std::make_unique<system_page_size> ();
203 std::unique_ptr<region::factory> region_factory_;
204 region_container regions_;
209 template <
typename Storage,
typename ResultType>
210 inline auto storage::segment_base_impl (Storage &
storage,
211 address::segment_type
const segment) noexcept
213 PSTORE_ASSERT (segment < storage.sat_->size ());
214 auto & e = (*storage.sat_)[segment];
215 PSTORE_ASSERT (e.is_valid ());
221 template <
typename Storage,
typename ResultType>
222 inline auto storage::address_to_pointer_impl (Storage & storage,
address const addr) noexcept
224 auto segment_base = storage.segment_base (addr.segment ());
226 return {segment_base,
227 std::static_pointer_cast<uint8_type> (segment_base).
get () + addr.offset ()};
238 #ifdef PSTORE_ALWAYS_SPANNING 241 return (*sat_)[addr.segment ()].region != (*sat_)[(addr + size - 1U).segment ()].region;
242 #endif // PSTORE_ALWAYS_SPANNING 247 template <
typename Traits,
typename Function>
249 Function copier)
const {
251 PSTORE_STATIC_ASSERT (std::numeric_limits<std::size_t>::max () <=
252 std::numeric_limits<std::uint64_t>::max ());
253 address::segment_type segment = addr.segment ();
254 PSTORE_STATIC_ASSERT (std::numeric_limits<decltype (segment)>::max () <= sat_elements);
255 sat_entry const & segment_pointer = (*sat_)[segment];
256 PSTORE_ASSERT (segment_pointer.
value !=
nullptr && segment_pointer.
region !=
nullptr &&
257 segment_pointer.is_valid ());
260 static_cast<typename Traits::in_store_pointer
> (segment_pointer.
value.get ()) +
263 static_cast<typename Traits::in_store_pointer
> (segment_pointer.
region->data ().get ());
264 PSTORE_ASSERT (in_store_ptr >= region_base &&
265 in_store_ptr <= region_base + segment_pointer.region->size ());
267 std::uint64_t copy_size = segment_pointer.
region->size () -
268 static_cast<std::uintptr_t
> (in_store_ptr - region_base);
269 static_assert (std::numeric_limits<std::size_t>::max () <=
270 std::numeric_limits<std::uint64_t>::max (),
271 "size_t must not be larger than uint64!");
272 copy_size = std::min (copy_size, std::uint64_t{size});
276 copier (in_store_ptr, p, copy_size);
279 for (p += copy_size, size -= copy_size; size > 0; p += copy_size, size -= copy_size) {
283 std::uint64_t
const inc =
285 PSTORE_ASSERT (inc < std::numeric_limits<address::segment_type>::max ());
286 PSTORE_ASSERT (segment + inc < sat_elements);
287 segment +=
static_cast<address::segment_type
> (inc);
289 region::memory_mapper_ptr
const &
region = (*sat_)[segment].region;
290 PSTORE_ASSERT (region !=
nullptr);
292 copy_size = std::min (static_cast<std::uint64_t> (size), region->size ());
293 in_store_ptr =
static_cast<typename Traits::in_store_pointer
> (region->data ().get ());
294 copier (in_store_ptr, p, copy_size);
300 #endif // PSTORE_CORE_STORAGE_HPP std::shared_ptr< void > value
A pointer to the data belonging to the segment represented by this entry in the segment address table...
Definition: storage.hpp:33
Definition: storage.hpp:97
std::shared_ptr< void const > segment_base(address::segment_type const segment) const noexcept
Definition: storage.hpp:146
Definition: address.hpp:81
static constexpr segment_type const max_segment
The largest legal segment value.
Definition: address.hpp:96
An entry in the segment address table.
Definition: storage.hpp:29
Definition: address.hpp:231
Definition: storage.hpp:93
void copy(address addr, std::size_t size, typename Traits::temp_pointer p, Function copier) const
This function performs the bulk of the work of creating a "shadow" block when a request spans more th...
Definition: storage.hpp:248
region::memory_mapper_ptr region
The memory-mapped region to which the 'value' pointer belongs.
Definition: storage.hpp:36
Definition: storage.hpp:58
Definition: nonpod2.cpp:40
Provides a member typedef inherit_const::type, which is defined as R const if T is a const type and R...
Definition: inherit_const.hpp:108
An implementation of the standard assert() macro with the exception that it will, on failure...
bool request_spans_regions(address const &addr, std::size_t size) const noexcept
Returns true if the given address range "spans" more than one region.
Definition: storage.hpp:232
static constexpr value_type const segment_size
The number of bytes in a segment.
Definition: address.hpp:98
typename std::conditional< std::is_const< typename std::remove_reference< T >::type >::value, RC, R >::type type
If T is const, R const otherwise R.
Definition: inherit_const.hpp:112
An abstract file class. Provides the interface for file access.
Definition: file.hpp:176
Functions for aligning values and pointers.