MySQL 8.0.30
Source Code Documentation
page_metadata.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2021, 2022, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is also distributed with certain software (including but not
10limited to OpenSSL) that is licensed under separate terms, as designated in a
11particular file or component or in included license documentation. The authors
12of MySQL hereby grant you an additional permission to link the program and
13your derivative works with the separately licensed software that they have
14included with MySQL.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
25*****************************************************************************/
26
27/** @file include/detail/ut/page_metadata.h
28 Implementation bits and pieces for metadata for normal and large (huge) page
29 allocations.
30 */
31
32#ifndef detail_ut_page_metadata_h
33#define detail_ut_page_metadata_h
34
37
38namespace ut {
39namespace detail {
40
41/** Types of pages currently supported by ut:: library functions */
42enum class Page_type { system_page = 0x10, large_page = 0x20 };
43
44/** Helper struct implementing the type which represents the metadata for all
45 types of page-aligned allocations, be it regular pages or huge-pages.
46
47 Concrete implementations such as Page_alloc or Large_page_alloc are
48 both implemented in terms of this basic building block. This is one way
49 which enables an easier implementation of higher-kinded convenience
50 library functions, e.g. huge-page allocation with fallback to regular pages.
51
52 Memory layout representation looks like the following:
53
54 --------------------------------
55 | DATALEN | PAGE-TYPE | VARLEN |
56 --------------------------------
57 \ \
58 0 \
59 CPU_PAGE_SIZE - 1
60
61 DATALEN field encodes total size of memory consumed and not only the size of
62 the DATA segment.
63
64 PAGE-TYPE field encodes the type of page this memory is backed up with.
65
66 VARLEN is the leftover variable-length segment that specialized
67 implementations can further make use of by deducing its size from the
68 following formulae: abs(CPU_PAGE_SIZE - sizeof(DATALEN) -
69 sizeof(PAGE-TYPE)). In code that would be std::abs(CPU_PAGE_SIZE -
70 sizeof(Page_alloc_metadata::datalen_t) -
71 sizeof(Page_alloc_metadata::page_type_t)).
72 Not used by this implementation.
73 */
75 /** This is how much tise metadata segment will be big. */
76 static constexpr auto len = CPU_PAGE_SIZE;
77
78 /** These are the types representing our memory fields. */
79 using datalen_t = size_t;
80 using page_type_t = size_t;
81
82 /** Sanity check so that we can be sure that the size of our metadata segment
83 is such so that the next segment coming after it (DATA) is always suitably
84 aligned (multiple of alignof(max_align_t).
85 */
86 static_assert(len % alignof(max_align_t) == 0,
87 "len must be divisible by alignof(max_align_t)");
88
89 /** Sanity check so that we can be sure that our metadata segment can fit
90 all our fields (datalen_t and page_type_t).
91 */
92 static_assert(sizeof(datalen_t) + sizeof(page_type_t) <= len,
93 "Metadata does not fit!");
94
95 /** Accessor to the datalen_t field. Returns its value.
96
97 @param[in] data Pointer to the DATA segment.
98 @return Value held by datalen_t field.
99 */
100 static inline datalen_t datalen(void *data) {
101 return *reinterpret_cast<datalen_t *>(static_cast<uint8_t *>(data) - len);
102 }
103
104 /** Accessor to the page_type_t field. Returns its value.
105
106 @param[in] data Pointer to the DATA segment.
107 @return Value held by page_type_t field, in particular Page_type.
108 */
109 static inline Page_type page_type(void *data) {
110 auto type = *reinterpret_cast<page_type_t *>(static_cast<uint8_t *>(data) -
111 len + sizeof(datalen_t));
112 return static_cast<Page_type>(type);
113 }
114
115 /** Accessor to the datalen_t field. Sets its value.
116
117 @param[in] mem Pointer to the memory, usually allocated through
118 large_page_alloc or page_alloc.
119 @param[in] length New value to be set into the field.
120 */
121 static inline void datalen(void *mem, size_t length) {
122 *reinterpret_cast<datalen_t *>(mem) = length;
123 }
124
125 /** Accessor to the page_type_t field. Sets its value.
126
127 @param[in] mem Pointer to the memory, usually allocated through
128 large_page_alloc or page_alloc.
129 @param[in] type New value to be set into the field.
130 */
131 static inline void page_type(void *mem, Page_type type) {
132 *reinterpret_cast<page_type_t *>(static_cast<uint8_t *>(mem) +
133 sizeof(datalen_t)) =
134 static_cast<page_type_t>(type);
135 }
136};
137
138/**
139 Helper struct implementing the type which represents the metadata for all
140 types of PFS-aware page-aligned allocations, be it regular pages or
141 huge-pages.
142
143 Concrete implementations such as Page_alloc_pfs or Large_page_alloc_pfs are
144 both implemented in terms of this basic building block. This is one way
145 which enables an easier implementation of higher-kinded convenience
146 library functions, e.g. huge-page allocation with fallback to regular
147 pages.
148
149 Memory layout representation looks like the following:
150
151 ---------------------------------------------------
152 | PFS-META | PAGE-TYPE | VARLEN | PFS-META-OFFSET |
153 ---------------------------------------------------
154 \ ^ \
155 0 | \
156 | CPU_PAGE_SIZE - 1
157 |
158 |
159 ---------------------------
160 | OWNER | DATALEN | KEY |
161 ---------------------------
162
163 OWNER field encodes the owning thread.
164 DATALEN field encodes total size of memory consumed and not only the size of
165 the DATA segment.
166 KEY field encodes the PFS/PSI key.
167
168 PAGE-TYPE field encodes the type of page this memory is backed up with.
169
170 VARLEN is the leftover variable-length segment that specialized
171 implementations can further make use of by deducing its size from the
172 following formulae: abs(CPU_PAGE_SIZE - sizeof(PFS-META-OFFSET) -
173 sizeof(PFS-META)). In code that would be std::abs(CPU_PAGE_SIZE -
174 PFS_metadata::size). Not used by this implementation.
175
176 PFS-META-OFFSET, strictly speaking, isn't neccesary in this case of
177 system-pages, where alignment is always known in compile-time and thus the
178 offset we will be storing into the PFS-META-OFFSET field is always going
179 to be the same for the given platform. So, rather than serializing this
180 piece of information into the memory as we do right now, we could very
181 well be storing it into the compile-time evaluated constexpr constant. The
182 reason why we don't do it is that there is no advantage (*) of doing so
183 while we would be introducing a disadvantage of having to maintain separate
184 specialization of PFS_metadata and code would be somewhat more fragmented.
185
186 (*) Extra space that we need to allocate in order to be able to fit the
187 PFS_metadata is going to be the same regardless if there is
188 PFS-META-OFFSET field or not. This is due to the fact that PFS-META
189 segment alone is larger than alignof(max_align_t) so in order to
190 keep the DATA segment suitably aligned (% alignof(max_align_t) == 0)
191 we must choose the size for the whole PFS segment that is a multiple
192 of alignof(max_align_t).
193
194 PFS-META-OFFSET is a field which allows us to recover the pointer to
195 PFS-META segment from a pointer to DATA segment.
196 */
199 using page_type_t = size_t;
200
201 /** This is how much this metadata segment will be big. */
202 static constexpr auto len = CPU_PAGE_SIZE;
203
204 /** Suitably-aligned offset for PAGE-TYPE field. */
205 static constexpr auto page_type_offset =
207
208 /** Sanity check so that we can be sure that the size of our metadata segment
209 is such so that the pointer to DATA segment is always suitably aligned
210 (multiple of alignof(max_align_t).
211 */
212 static_assert(len % alignof(max_align_t) == 0,
213 "len must be divisible by alignof(max_align_t)");
214
215 /** Accessor to the page_type_t field. Returns its value.
216
217 @param[in] data Pointer to the DATA segment.
218 @return Value held by page_type_t field, in particular Page_type.
219 */
220 static inline Page_type page_type(void *data) {
221 auto type = *reinterpret_cast<page_type_t *>(
222 static_cast<uint8_t *>(pfs_metadata::deduce_pfs_meta(data)) +
224 return static_cast<Page_type>(type);
225 }
226
227 /** Accessor to the page_type_t field. Sets its value.
228
229 @param[in] mem Pointer to the memory, usually allocated through
230 large_page_alloc or page_alloc.
231 @param[in] type New value to be set into the field.
232 */
233 static inline void page_type(void *mem, Page_type type) {
234 *reinterpret_cast<page_type_t *>(static_cast<uint8_t *>(mem) +
236 static_cast<page_type_t>(type);
237 }
238};
239
240} // namespace detail
241} // namespace ut
242
243#endif
Small helper functions.
#define CPU_PAGE_SIZE
Definition: config.h:311
Definition: ut0tuple.h:56
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:75
constexpr size_t calc_align(size_t n, size_t m)
Calculates the smallest multiple of m that is not smaller than n when m is a power of two.
Definition: helper.h:44
Page_type
Types of pages currently supported by ut:: library functions.
Definition: page_metadata.h:42
This file contains a set of libraries providing overloads for regular dynamic allocation routines whi...
Definition: aligned_alloc.h:47
required string type
Definition: replication_group_member_actions.proto:33
static MEM_ROOT mem
Definition: sql_servers.cc:98
Implementation bits and pieces for PFS metadata handling.
Memory layout representation of PFS metadata segment that is used by the allocator variants which als...
Definition: pfs.h:85
static constexpr auto meta_size
Metadata size.
Definition: pfs.h:96
static void * deduce_pfs_meta(data_segment_ptr data) noexcept
Helper function which deduces the pointer to the beginning of PFS metadata segment given the pointer ...
Definition: pfs.h:155
Helper struct implementing the type which represents the metadata for all types of PFS-aware page-ali...
Definition: page_metadata.h:197
static void page_type(void *mem, Page_type type)
Accessor to the page_type_t field.
Definition: page_metadata.h:233
static constexpr auto len
This is how much this metadata segment will be big.
Definition: page_metadata.h:202
size_t page_type_t
Definition: page_metadata.h:199
static Page_type page_type(void *data)
Sanity check so that we can be sure that the size of our metadata segment is such so that the pointer...
Definition: page_metadata.h:220
static constexpr auto page_type_offset
Suitably-aligned offset for PAGE-TYPE field.
Definition: page_metadata.h:205
Helper struct implementing the type which represents the metadata for all types of page-aligned alloc...
Definition: page_metadata.h:74
static constexpr auto len
This is how much tise metadata segment will be big.
Definition: page_metadata.h:76
static Page_type page_type(void *data)
Accessor to the page_type_t field.
Definition: page_metadata.h:109
static datalen_t datalen(void *data)
Sanity check so that we can be sure that the size of our metadata segment is such so that the next se...
Definition: page_metadata.h:100
static void datalen(void *mem, size_t length)
Accessor to the datalen_t field.
Definition: page_metadata.h:121
size_t page_type_t
Definition: page_metadata.h:80
static void page_type(void *mem, Page_type type)
Accessor to the page_type_t field.
Definition: page_metadata.h:131
size_t datalen_t
These are the types representing our memory fields.
Definition: page_metadata.h:79