29#ifndef _GLIBCXX_MEMORY_RESOURCE
30#define _GLIBCXX_MEMORY_RESOURCE 1
32#pragma GCC system_header
36#if __cplusplus >= 201703L
44namespace std _GLIBCXX_VISIBILITY(default)
46_GLIBCXX_BEGIN_NAMESPACE_VERSION
49#ifdef _GLIBCXX_HAS_GTHREADS
51# define __cpp_lib_memory_resource 201603L
54# define __cpp_lib_memory_resource 1
57#if __cplusplus >= 202002L
58# define __cpp_lib_polymorphic_allocator 201902L
59 template<
typename _Tp = std::
byte>
60 class polymorphic_allocator;
66 [[nodiscard, __gnu__::__returns_nonnull__, __gnu__::__const__]]
71 [[nodiscard, __gnu__::__returns_nonnull__, __gnu__::__const__]]
73 null_memory_resource() noexcept;
76 [[__gnu__::__returns_nonnull__]]
81 [[__gnu__::__returns_nonnull__]]
83 get_default_resource() noexcept;
87#ifdef _GLIBCXX_HAS_GTHREADS
91 class monotonic_buffer_resource;
108 size_t largest_required_pool_block = 0;
112 class __pool_resource
121 __pool_resource(
const __pool_resource&) =
delete;
122 __pool_resource& operator=(
const __pool_resource&) =
delete;
126 allocate(
size_t __bytes,
size_t __alignment);
130 deallocate(
void* __p,
size_t __bytes,
size_t __alignment);
134 void release()
noexcept;
137 {
return _M_unpooled.get_allocator().resource(); }
141 _Pool* _M_alloc_pools();
143 const pool_options _M_opts;
148 _GLIBCXX_STD_C::pmr::vector<_BigBlock> _M_unpooled;
153#ifdef _GLIBCXX_HAS_GTHREADS
160 __attribute__((__nonnull__));
168 __attribute__((__nonnull__))
186 upstream_resource()
const noexcept
187 __attribute__((__returns_nonnull__))
188 {
return _M_impl.resource(); }
190 pool_options options()
const noexcept {
return _M_impl._M_opts; }
194 do_allocate(
size_t __bytes,
size_t __alignment)
override;
197 do_deallocate(
void* __p,
size_t __bytes,
size_t __alignment)
override;
201 {
return this == &__other; }
210 auto _M_thread_specific_pools()
noexcept;
212 __pool_resource _M_impl;
213 __gthread_key_t _M_key;
215 _TPools* _M_tpools =
nullptr;
224 [[__gnu__::__nonnull__]]
232 [[__gnu__::__nonnull__]]
251 [[__gnu__::__returns_nonnull__]]
253 upstream_resource()
const noexcept
254 {
return _M_impl.resource(); }
256 pool_options options()
const noexcept {
return _M_impl._M_opts; }
260 do_allocate(
size_t __bytes,
size_t __alignment)
override;
263 do_deallocate(
void* __p,
size_t __bytes,
size_t __alignment)
override;
267 {
return this == &__other; }
270 using _Pool = __pool_resource::_Pool;
272 auto _M_find_pool(
size_t)
noexcept;
274 __pool_resource _M_impl;
275 _Pool* _M_pools =
nullptr;
283 __attribute__((__nonnull__))
284 : _M_upstream(__upstream)
285 { _GLIBCXX_DEBUG_ASSERT(__upstream !=
nullptr); }
287 monotonic_buffer_resource(
size_t __initial_size,
288 memory_resource* __upstream)
noexcept
289 __attribute__((__nonnull__))
290 : _M_next_bufsiz(__initial_size),
291 _M_upstream(__upstream)
293 _GLIBCXX_DEBUG_ASSERT(__upstream !=
nullptr);
294 _GLIBCXX_DEBUG_ASSERT(__initial_size > 0);
297 monotonic_buffer_resource(
void* __buffer,
size_t __buffer_size,
298 memory_resource* __upstream)
noexcept
299 __attribute__((__nonnull__(4)))
300 : _M_current_buf(__buffer), _M_avail(__buffer_size),
301 _M_next_bufsiz(_S_next_bufsize(__buffer_size)),
302 _M_upstream(__upstream),
303 _M_orig_buf(__buffer), _M_orig_size(__buffer_size)
305 _GLIBCXX_DEBUG_ASSERT(__upstream !=
nullptr);
306 _GLIBCXX_DEBUG_ASSERT(__buffer !=
nullptr || __buffer_size == 0);
309 monotonic_buffer_resource() noexcept
310 : monotonic_buffer_resource(get_default_resource())
314 monotonic_buffer_resource(
size_t __initial_size) noexcept
318 monotonic_buffer_resource(
void* __buffer,
size_t __buffer_size) noexcept
322 monotonic_buffer_resource(
const monotonic_buffer_resource&) =
delete;
324 virtual ~monotonic_buffer_resource();
326 monotonic_buffer_resource&
327 operator=(
const monotonic_buffer_resource&) =
delete;
333 _M_release_buffers();
336 if ((_M_current_buf = _M_orig_buf))
338 _M_avail = _M_orig_size;
339 _M_next_bufsiz = _S_next_bufsize(_M_orig_size);
344 _M_next_bufsiz = _M_orig_size;
349 upstream_resource() const noexcept
350 __attribute__((__returns_nonnull__))
351 {
return _M_upstream; }
355 do_allocate(
size_t __bytes,
size_t __alignment)
override
357 if (__builtin_expect(__bytes == 0,
false))
360 void* __p =
std::align(__alignment, __bytes, _M_current_buf, _M_avail);
361 if (__builtin_expect(__p ==
nullptr,
false))
363 _M_new_buffer(__bytes, __alignment);
364 __p = _M_current_buf;
366 _M_current_buf = (
char*)_M_current_buf + __bytes;
372 do_deallocate(
void*,
size_t,
size_t)
override
376 do_is_equal(
const memory_resource& __other)
const noexcept override
377 {
return this == &__other; }
383 _M_new_buffer(
size_t __bytes,
size_t __alignment);
387 _M_release_buffers() noexcept;
390 _S_next_bufsize(
size_t __buffer_size) noexcept
392 if (__builtin_expect(__buffer_size == 0,
false))
394 return __buffer_size * _S_growth_factor;
397 static constexpr size_t _S_init_bufsize = 128 *
sizeof(
void*);
398 static constexpr float _S_growth_factor = 1.5;
400 void* _M_current_buf =
nullptr;
402 size_t _M_next_bufsiz = _S_init_bufsize;
405 memory_resource*
const _M_upstream;
406 void*
const _M_orig_buf =
nullptr;
407 size_t const _M_orig_size = _M_next_bufsiz;
410 _Chunk* _M_head =
nullptr;
414_GLIBCXX_END_NAMESPACE_VERSION
memory_resource * new_delete_resource() noexcept
A pmr::memory_resource that uses new to allocate memory.
memory_resource * get_default_resource() noexcept
Get the current default memory resource pointer.
void * align(size_t __align, size_t __size, void *&__ptr, size_t &__space) noexcept
Fit aligned storage in buffer.
ISO C++ entities toplevel namespace is std.
Parameters for tuning a pool resource's behaviour.
size_t max_blocks_per_chunk
Upper limit on number of blocks in a chunk.
A thread-safe memory resource that manages pools of fixed-size blocks.
A non-thread-safe memory resource that manages pools of fixed-size blocks.
The standard shared mutex type.
A simple scoped lock type.