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