libstdc++
memory_resource
Go to the documentation of this file.
1
/
/
<
memory_resource
>
-
*
-
C
+
+
-
*
-
2
3
/
/
Copyright
(
C
)
2018-2025
Free
Software
Foundation
,
Inc
.
4
/
/
5
/
/
This
file
is
part
of
the
GNU
ISO
C
+
+
Library
.
This
library
is
free
6
/
/
software
;
you
can
redistribute
it
and
/
or
modify
it
under
the
7
/
/
terms
of
the
GNU
General
Public
License
as
published
by
the
8
/
/
Free
Software
Foundation
;
either
version
3
,
or
(
at
your
option
)
9
/
/
any
later
version
.
10
11
/
/
This
library
is
distributed
in
the
hope
that
it
will
be
useful
,
12
/
/
but
WITHOUT
ANY
WARRANTY
;
without
even
the
implied
warranty
of
13
/
/
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE
.
See
the
14
/
/
GNU
General
Public
License
for
more
details
.
15
16
/
/
Under
Section
7
of
GPL
version
3
,
you
are
granted
additional
17
/
/
permissions
described
in
the
GCC
Runtime
Library
Exception
,
version
18
/
/
3
.
1
,
as
published
by
the
Free
Software
Foundation
.
19
20
/
/
You
should
have
received
a
copy
of
the
GNU
General
Public
License
and
21
/
/
a
copy
of
the
GCC
Runtime
Library
Exception
along
with
this
program
;
22
/
/
see
the
files
COPYING3
and
COPYING
.
RUNTIME
respectively
.
If
not
,
see
23
/
/
<
http
:
/
/
www
.
gnu
.
org
/
licenses
/
>
.
24
25
/
*
*
@
file
include
/
memory_resource
26
*
This
is
a
Standard
C
+
+
Library
header
.
27
*
28
*
This
header
declares
the
@
ref
pmr
(
std
:
:
pmr
)
memory
resources
.
29
*
@
ingroup
pmr
30
*
/
31
32
#ifndef _GLIBCXX_MEMORY_RESOURCE
33
#define _GLIBCXX_MEMORY_RESOURCE 1
34
35
#ifdef _GLIBCXX_SYSHDR
36
#pragma GCC system_header
37
#endif
38
39
#include <bits/requires_hosted.h> // polymorphic allocation
40
41
#define __glibcxx_want_polymorphic_allocator
42
#define __glibcxx_want_memory_resource
43
#include <bits/version.h>
44
45
#if __cplusplus >= 201703L
46
47
/
*
*
48
*
@
defgroup
pmr
Polymorphic
memory
resources
49
*
50
*
@
anchor
pmr
51
*
@
ingroup
memory
52
*
@
since
C
+
+
17
53
*
54
*
Memory
resources
are
classes
that
implement
the
`
std
:
:
pmr
:
:
memory_resource
`
55
*
interface
for
allocating
and
deallocating
memory
.
Unlike
traditional
C
+
+
56
*
allocators
,
memory
resources
are
not
value
types
and
are
used
via
pointers
57
*
to
the
abstract
base
class
.
They
are
only
responsible
for
allocating
and
58
*
deallocating
,
not
for
construction
and
destruction
of
objects
.
As
a
result
,
59
*
memory
resources
just
allocate
raw
memory
as
type
`
void
*
`
and
are
not
60
*
templates
that
allocate
/
deallocate
and
construct
/
destroy
a
specific
type
.
61
*
62
*
The
class
template
`
std
:
:
pmr
:
:
polymorphic_allocator
`
is
an
allocator
that
63
*
uses
a
memory
resource
for
its
allocations
.
64
*
/
65
66
#include <bits/memory_resource.h>
67
#include <vector> // vector
68
#include <shared_mutex> // shared_mutex
69
#include <bits/align.h> // align
70
#include <debug/assertions.h>
71
72
namespace
std
_GLIBCXX_VISIBILITY
(
default
)
73
{
74
_GLIBCXX_BEGIN_NAMESPACE_VERSION
75
namespace
pmr
76
{
77
78
#ifdef __cpp_lib_polymorphic_allocator // C++ >= 20 && HOSTED
79
template
<
typename
_Tp
=
std
:
:
byte
>
80
class
polymorphic_allocator
;
81
#endif
82
83
/
/
Global
memory
resources
84
85
/
/
/
A
pmr
:
:
memory_resource
that
uses
`
new
`
to
allocate
memory
86
/
*
*
87
*
@
ingroup
pmr
88
*
@
headerfile
memory_resource
89
*
@
since
C
+
+
17
90
*
/
91
[[
nodiscard
,
__gnu__
:
:
__returns_nonnull__
,
__gnu__
:
:
__const__
]]
92
memory_resource
*
93
new_delete_resource
(
)
noexcept
;
94
95
/
/
/
A
pmr
:
:
memory_resource
that
always
throws
`
bad_alloc
`
96
[[
nodiscard
,
__gnu__
:
:
__returns_nonnull__
,
__gnu__
:
:
__const__
]]
97
memory_resource
*
98
null_memory_resource
(
)
noexcept
;
99
100
/
/
/
Replace
the
default
memory
resource
pointer
101
[[
__gnu__
:
:
__returns_nonnull__
]]
102
memory_resource
*
103
set_default_resource(memory_resource* __r) noexcept;
104
105
/
/
/
Get
the
current
default
memory
resource
pointer
106
[[
__gnu__
:
:
__returns_nonnull__
]]
107
memory_resource
*
108
get_default_resource
(
)
noexcept
;
109
110
/
/
Pool
resource
classes
111
struct
pool_options
;
112
#if __cpp_lib_memory_resource >= 201603L // C++ >= 17 && hosted && gthread
113
class
synchronized_pool_resource
;
114
#endif
115
class
unsynchronized_pool_resource
;
116
class
monotonic_buffer_resource
;
117
118
/
/
/
Parameters
for
tuning
a
pool
resource
'
s
behaviour
.
119
/
*
*
120
*
@
ingroup
pmr
121
*
@
headerfile
memory_resource
122
*
@
since
C
+
+
17
123
*
/
124
struct
pool_options
125
{
126
/
*
*
@
brief
Upper
limit
on
number
of
blocks
in
a
chunk
.
127
*
128
*
A
lower
value
prevents
allocating
huge
chunks
that
could
remain
mostly
129
*
unused
,
but
means
pools
will
need
to
replenished
more
frequently
.
130
*
/
131
size_t
max_blocks_per_chunk
=
0
;
132
133
/
*
@
brief
Largest
block
size
(
in
bytes
)
that
should
be
served
from
pools
.
134
*
135
*
Larger
allocations
will
be
served
directly
by
the
upstream
resource
,
136
*
not
from
one
of
the
pools
managed
by
the
pool
resource
.
137
*
/
138
size_t
largest_required_pool_block
=
0
;
139
};
140
141
/
/
Common
implementation
details
for
un
-
/
synchronized
pool
resources
.
142
class
__pool_resource
143
{
144
friend
class
synchronized_pool_resource
;
145
friend
class
unsynchronized_pool_resource
;
146
147
__pool_resource
(
const
pool_options
&
__opts
,
memory_resource
*
__upstream
)
;
148
149
~
__pool_resource
(
)
;
150
151
__pool_resource
(
const
__pool_resource
&
)
=
delete
;
152
__pool_resource
&
operator
=
(
const
__pool_resource
&
)
=
delete
;
153
154
/
/
Allocate
a
large
unpooled
block
.
155
void
*
156
allocate
(
size_t
__bytes
,
size_t
__alignment
)
;
157
158
/
/
Deallocate
a
large
unpooled
block
.
159
void
160
deallocate
(
void
*
__p
,
size_t
__bytes
,
size_t
__alignment
)
;
161
162
163
/
/
Deallocate
unpooled
memory
.
164
void
release
(
)
noexcept
;
165
166
memory_resource
*
resource
(
)
const
noexcept
167
{
return
_M_unpooled
.
get_allocator
(
)
.
resource
(
)
; }
168
169
struct
_Pool
;
170
171
_Pool
*
_M_alloc_pools
(
)
;
172
173
const
pool_options
_M_opts
;
174
175
struct
_BigBlock
;
176
/
/
Collection
of
blocks
too
big
for
any
pool
,
sorted
by
address
.
177
/
/
This
also
stores
the
only
copy
of
the
upstream
memory
resource
pointer
.
178
_GLIBCXX_STD_C
:
:
pmr
:
:
vector
<
_BigBlock
>
_M_unpooled
;
179
180
const
int
_M_npools
;
181
};
182
183
#if __cpp_lib_memory_resource >= 201603L // C++ >= 17 && hosted && gthread
184
/
/
/
A
thread
-
safe
memory
resource
that
manages
pools
of
fixed
-
size
blocks
.
185
/
*
*
186
*
@
ingroup
pmr
187
*
@
headerfile
memory_resource
188
*
@
since
C
+
+
17
189
*
/
190
class
synchronized_pool_resource
:
public
memory_resource
191
{
192
public
:
193
synchronized_pool_resource
(
const
pool_options
&
__opts
,
194
memory_resource
*
__upstream
)
195
__attribute__
(
(
__nonnull__
)
)
;
196
197
synchronized_pool_resource
(
)
198
:
synchronized_pool_resource
(
pool_options
(
)
,
get_default_resource
(
)
)
199
{ }
200
201
explicit
202
synchronized_pool_resource
(
memory_resource
*
__upstream
)
203
__attribute__
(
(
__nonnull__
)
)
204
:
synchronized_pool_resource
(
pool_options
(
)
,
__upstream
)
205
{ }
206
207
explicit
208
synchronized_pool_resource
(
const
pool_options
&
__opts
)
209
:
synchronized_pool_resource
(
__opts
,
get_default_resource
(
)
)
{ }
210
211
synchronized_pool_resource
(
const
synchronized_pool_resource
&
)
=
delete
;
212
213
virtual
~
synchronized_pool_resource
(
)
;
214
215
synchronized_pool_resource
&
216
operator
=
(
const
synchronized_pool_resource
&
)
=
delete
;
217
218
void
release
(
)
;
219
220
memory_resource
*
221
upstream_resource
(
)
const
noexcept
222
__attribute__
(
(
__returns_nonnull__
)
)
223
{
return
_M_impl
.
resource
(
)
; }
224
225
pool_options
options
(
)
const
noexcept
{
return
_M_impl
.
_M_opts
; }
226
227
protected
:
228
void
*
229
do_allocate
(
size_t
__bytes
,
size_t
__alignment
)
override
;
230
231
void
232
do_deallocate
(
void
*
__p
,
size_t
__bytes
,
size_t
__alignment
)
override
;
233
234
bool
235
do_is_equal
(
const
memory_resource
&
__other
)
const
noexcept
override
236
{
return
this
==
&
__other
; }
237
238
public
:
239
/
/
Thread
-
specific
pools
(
only
public
for
access
by
implementation
details
)
240
struct
_TPools
;
241
242
private
:
243
_TPools
*
_M_alloc_tpools
(
lock_guard
<
shared_mutex
>
&
)
;
244
_TPools
*
_M_alloc_shared_tpools
(
lock_guard
<
shared_mutex
>
&
)
;
245
auto
_M_thread_specific_pools
(
)
noexcept
;
246
247
__pool_resource
_M_impl
;
248
__gthread_key_t
_M_key
;
249
/
/
Linked
list
of
thread
-
specific
pools
.
All
threads
share
_M_tpools
[
0
]
.
250
_TPools
*
_M_tpools
=
nullptr
;
251
mutable
shared_mutex
_M_mx
;
252
};
253
#endif // __cpp_lib_memory_resource >= 201603L
254
255
/
/
/
A
non
-
thread
-
safe
memory
resource
that
manages
pools
of
fixed
-
size
blocks
.
256
/
*
*
257
*
@
ingroup
pmr
258
*
@
headerfile
memory_resource
259
*
@
since
C
+
+
17
260
*
/
261
class
unsynchronized_pool_resource
:
public
memory_resource
262
{
263
public
:
264
[[
__gnu__
:
:
__nonnull__
]]
265
unsynchronized_pool_resource
(
const
pool_options
&
__opts
,
266
memory_resource
*
__upstream
)
;
267
268
unsynchronized_pool_resource
(
)
269
:
unsynchronized_pool_resource
(
pool_options
(
)
,
get_default_resource
(
)
)
270
{ }
271
272
[[
__gnu__
:
:
__nonnull__
]]
273
explicit
274
unsynchronized_pool_resource
(
memory_resource
*
__upstream
)
275
:
unsynchronized_pool_resource
(
pool_options
(
)
,
__upstream
)
276
{ }
277
278
explicit
279
unsynchronized_pool_resource
(
const
pool_options
&
__opts
)
280
:
unsynchronized_pool_resource
(
__opts
,
get_default_resource
(
)
)
{ }
281
282
unsynchronized_pool_resource
(
const
unsynchronized_pool_resource
&
)
=
delete
;
283
284
virtual
~
unsynchronized_pool_resource
(
)
;
285
286
unsynchronized_pool_resource
&
287
operator
=
(
const
unsynchronized_pool_resource
&
)
=
delete
;
288
289
void
release
(
)
;
290
291
[[
__gnu__
:
:
__returns_nonnull__
]]
292
memory_resource
*
293
upstream_resource
(
)
const
noexcept
294
{
return
_M_impl
.
resource
(
)
; }
295
296
pool_options
options
(
)
const
noexcept
{
return
_M_impl
.
_M_opts
; }
297
298
protected
:
299
void
*
300
do_allocate
(
size_t
__bytes
,
size_t
__alignment
)
override
;
301
302
void
303
do_deallocate
(
void
*
__p
,
size_t
__bytes
,
size_t
__alignment
)
override
;
304
305
bool
306
do_is_equal
(
const
memory_resource
&
__other
)
const
noexcept
override
307
{
return
this
==
&
__other
; }
308
309
private
:
310
using
_Pool
=
__pool_resource
:
:
_Pool
;
311
312
auto
_M_find_pool
(
size_t
)
noexcept
;
313
314
__pool_resource
_M_impl
;
315
_Pool
*
_M_pools
=
nullptr
;
316
};
317
318
/
/
/
A
memory
resource
that
allocates
from
a
fixed
-
size
buffer
.
319
/
*
*
320
*
The
main
feature
of
a
`
pmr
:
:
monotonic_buffer_resource
`
is
that
its
321
*
`
do_deallocate
`
does
nothing
.
This
makes
it
very
fast
because
there
is
no
322
*
need
to
manage
a
free
list
,
and
every
allocation
simply
returns
a
new
323
*
block
of
memory
,
rather
than
searching
for
a
suitably
-
sized
free
block
.
324
*
Because
deallocating
is
a
no
-
op
,
the
amount
of
memory
used
by
the
resource
325
*
only
grows
until
`
release
(
)
`
(
or
the
destructor
)
is
called
to
return
all
326
*
memory
to
upstream
.
327
*
328
*
A
`
monotonic_buffer_resource
`
can
be
initialized
with
a
buffer
that
329
*
will
be
used
to
satisfy
all
allocation
requests
,
until
the
buffer
is
full
.
330
*
After
that
a
new
buffer
will
be
allocated
from
the
upstream
resource
.
331
*
By
using
a
stack
buffer
and
`
pmr
:
:
null_memory_resource
(
)
`
as
the
upstream
332
*
you
can
get
a
memory
resource
that
only
uses
the
stack
and
never
333
*
dynamically
allocates
.
334
*
335
*
@
ingroup
pmr
336
*
@
headerfile
memory_resource
337
*
@
since
C
+
+
17
338
*
/
339
class
monotonic_buffer_resource
:
public
memory_resource
340
{
341
public
:
342
explicit
343
monotonic_buffer_resource
(
memory_resource
*
__upstream
)
noexcept
344
__attribute__
(
(
__nonnull__
)
)
345
:
_M_upstream
(
__upstream
)
346
{
_GLIBCXX_DEBUG_ASSERT
(
__upstream
!=
nullptr
)
; }
347
348
monotonic_buffer_resource
(
size_t
__initial_size
,
349
memory_resource
*
__upstream
)
noexcept
350
__attribute__
(
(
__nonnull__
)
)
351
:
_M_next_bufsiz
(
__initial_size
)
,
352
_M_upstream
(
__upstream
)
353
{
354
_GLIBCXX_DEBUG_ASSERT
(
__upstream
!=
nullptr
)
;
355
_GLIBCXX_DEBUG_ASSERT
(
__initial_size
>
0
)
;
356
}
357
358
monotonic_buffer_resource
(
void
*
__buffer
,
size_t
__buffer_size
,
359
memory_resource
*
__upstream
)
noexcept
360
__attribute__
(
(
__nonnull__
(
4
)
)
)
361
:
_M_current_buf
(
__buffer
)
,
_M_avail
(
__buffer_size
)
,
362
_M_next_bufsiz
(
_S_next_bufsize
(
__buffer_size
)
)
,
363
_M_upstream
(
__upstream
)
,
364
_M_orig_buf
(
__buffer
)
,
_M_orig_size
(
__buffer_size
)
365
{
366
_GLIBCXX_DEBUG_ASSERT
(
__upstream
!=
nullptr
)
;
367
_GLIBCXX_DEBUG_ASSERT
(
__buffer
!=
nullptr
||
__buffer_size
==
0
)
;
368
}
369
370
monotonic_buffer_resource
(
)
noexcept
371
:
monotonic_buffer_resource
(
get_default_resource
(
)
)
372
{ }
373
374
explicit
375
monotonic_buffer_resource
(
size_t
__initial_size
)
noexcept
376
:
monotonic_buffer_resource
(
__initial_size
,
get_default_resource
(
)
)
377
{ }
378
379
monotonic_buffer_resource
(
void
*
__buffer
,
size_t
__buffer_size
)
noexcept
380
:
monotonic_buffer_resource
(
__buffer
,
__buffer_size
,
get_default_resource
(
)
)
381
{ }
382
383
monotonic_buffer_resource
(
const
monotonic_buffer_resource
&
)
=
delete
;
384
385
virtual
~
monotonic_buffer_resource
(
)
;
/
/
key
function
386
387
monotonic_buffer_resource
&
388
operator
=
(
const
monotonic_buffer_resource
&
)
=
delete
;
389
390
void
391
release
(
)
noexcept
392
{
393
if
(
_M_head
)
394
_M_release_buffers
(
)
;
395
396
/
/
reset
to
initial
state
at
contruction
:
397
if
(
(
_M_current_buf
=
_M_orig_buf
)
)
398
{
399
_M_avail
=
_M_orig_size
;
400
_M_next_bufsiz
=
_S_next_bufsize
(
_M_orig_size
)
;
401
}
402
else
403
{
404
_M_avail
=
0
;
405
_M_next_bufsiz
=
_M_orig_size
;
406
}
407
}
408
409
memory_resource
*
410
upstream_resource
(
)
const
noexcept
411
__attribute__
(
(
__returns_nonnull__
)
)
412
{
return
_M_upstream
; }
413
414
protected
:
415
void
*
416
do_allocate
(
size_t
__bytes
,
size_t
__alignment
)
override
417
{
418
if
(
__builtin_expect
(
__bytes
==
0
,
false
)
)
419
__bytes
=
1
;
/
/
Ensures
we
don
'
t
return
the
same
pointer
twice
.
420
421
void
*
__p
=
std
:
:
align
(
__alignment
,
__bytes
,
_M_current_buf
,
_M_avail
)
;
422
if
(
__builtin_expect
(
__p
==
nullptr
,
false
)
)
423
{
424
_M_new_buffer
(
__bytes
,
__alignment
)
;
425
__p
=
_M_current_buf
;
426
}
427
_M_current_buf
=
(
char
*
)
_M_current_buf
+
__bytes
;
428
_M_avail
-=
__bytes
;
429
return
__p
;
430
}
431
432
void
433
do_deallocate
(
void
*
,
size_t
,
size_t
)
override
434
{ }
435
436
bool
437
do_is_equal
(
const
memory_resource
&
__other
)
const
noexcept
override
438
{
return
this
==
&
__other
; }
439
440
private
:
441
/
/
Update
_M_current_buf
and
_M_avail
to
refer
to
a
new
buffer
with
442
/
/
at
least
the
specified
size
and
alignment
,
allocated
from
upstream
.
443
void
444
_M_new_buffer
(
size_t
__bytes
,
size_t
__alignment
)
;
445
446
/
/
Deallocate
all
buffers
obtained
from
upstream
.
447
void
448
_M_release_buffers
(
)
noexcept
;
449
450
static
size_t
451
_S_next_bufsize
(
size_t
__buffer_size
)
noexcept
452
{
453
if
(
__builtin_expect
(
__buffer_size
==
0
,
false
)
)
454
__buffer_size
=
1
;
455
return
__buffer_size
*
_S_growth_factor
;
456
}
457
458
static
constexpr
size_t
_S_init_bufsize
=
128
*
sizeof
(
void
*
)
;
459
static
constexpr
float
_S_growth_factor
=
1
.
5
;
460
461
void
*
_M_current_buf
=
nullptr
;
462
size_t
_M_avail
=
0
;
463
size_t
_M_next_bufsiz
=
_S_init_bufsize
;
464
465
/
/
Initial
values
set
at
construction
and
reused
by
release
(
)
:
466
memory_resource
*
const
_M_upstream
;
467
void
*
const
_M_orig_buf
=
nullptr
;
468
size_t
const
_M_orig_size
=
_M_next_bufsiz
;
469
470
class
_Chunk
;
471
_Chunk
*
_M_head
=
nullptr
;
472
};
473
474
}
/
/
namespace
pmr
475
_GLIBCXX_END_NAMESPACE_VERSION
476
}
/
/
namespace
std
477
478
#endif // C++17
479
#endif // _GLIBCXX_MEMORY_RESOURCE
memory_resource
Generated by
1.13.2