32#ifndef _GLIBCXX_MEMORY_RESOURCE
33#define _GLIBCXX_MEMORY_RESOURCE 1
35#pragma GCC system_header
39#define __glibcxx_want_polymorphic_allocator
40#define __glibcxx_want_memory_resource
43#if __cplusplus >= 201703L
70namespace std _GLIBCXX_VISIBILITY(default)
72_GLIBCXX_BEGIN_NAMESPACE_VERSION
76#ifdef __cpp_lib_polymorphic_allocator
77 template<
typename _Tp = std::
byte>
78 class polymorphic_allocator;
89 [[nodiscard, __gnu__::__returns_nonnull__, __gnu__::__const__]]
94 [[nodiscard, __gnu__::__returns_nonnull__, __gnu__::__const__]]
96 null_memory_resource() noexcept;
99 [[__gnu__::__returns_nonnull__]]
104 [[__gnu__::__returns_nonnull__]]
106 get_default_resource() noexcept;
110#if __cpp_lib_memory_resource >= 201603L
111 class synchronized_pool_resource;
136 size_t largest_required_pool_block = 0;
140 class __pool_resource
142 friend class synchronized_pool_resource;
149 __pool_resource(
const __pool_resource&) =
delete;
150 __pool_resource& operator=(
const __pool_resource&) =
delete;
154 allocate(
size_t __bytes,
size_t __alignment);
158 deallocate(
void* __p,
size_t __bytes,
size_t __alignment);
162 void release()
noexcept;
165 {
return _M_unpooled.get_allocator().resource(); }
169 _Pool* _M_alloc_pools();
171 const pool_options _M_opts;
176 _GLIBCXX_STD_C::pmr::vector<_BigBlock> _M_unpooled;
181#if __cpp_lib_memory_resource >= 201603L
188 class synchronized_pool_resource :
public memory_resource
191 synchronized_pool_resource(
const pool_options& __opts,
192 memory_resource* __upstream)
193 __attribute__((__nonnull__));
195 synchronized_pool_resource()
196 : synchronized_pool_resource(pool_options(), get_default_resource())
200 synchronized_pool_resource(memory_resource* __upstream)
201 __attribute__((__nonnull__))
202 : synchronized_pool_resource(pool_options(), __upstream)
206 synchronized_pool_resource(
const pool_options& __opts)
209 synchronized_pool_resource(
const synchronized_pool_resource&) =
delete;
211 virtual ~synchronized_pool_resource();
213 synchronized_pool_resource&
214 operator=(
const synchronized_pool_resource&) =
delete;
219 upstream_resource() const noexcept
220 __attribute__((__returns_nonnull__))
221 {
return _M_impl.resource(); }
223 pool_options options() const noexcept {
return _M_impl._M_opts; }
227 do_allocate(
size_t __bytes,
size_t __alignment)
override;
230 do_deallocate(
void* __p,
size_t __bytes,
size_t __alignment)
override;
233 do_is_equal(
const memory_resource& __other)
const noexcept override
234 {
return this == &__other; }
241 _TPools* _M_alloc_tpools(lock_guard<shared_mutex>&);
242 _TPools* _M_alloc_shared_tpools(lock_guard<shared_mutex>&);
243 auto _M_thread_specific_pools() noexcept;
245 __pool_resource _M_impl;
246 __gthread_key_t _M_key;
248 _TPools* _M_tpools =
nullptr;
249 mutable shared_mutex _M_mx;
262 [[__gnu__::__nonnull__]]
270 [[__gnu__::__nonnull__]]
289 [[__gnu__::__returns_nonnull__]]
291 upstream_resource()
const noexcept
292 {
return _M_impl.resource(); }
294 pool_options options()
const noexcept {
return _M_impl._M_opts; }
298 do_allocate(
size_t __bytes,
size_t __alignment)
override;
301 do_deallocate(
void* __p,
size_t __bytes,
size_t __alignment)
override;
305 {
return this == &__other; }
308 using _Pool = __pool_resource::_Pool;
310 auto _M_find_pool(
size_t)
noexcept;
312 __pool_resource _M_impl;
313 _Pool* _M_pools =
nullptr;
342 __attribute__((__nonnull__))
343 : _M_upstream(__upstream)
344 { _GLIBCXX_DEBUG_ASSERT(__upstream !=
nullptr); }
348 __attribute__((__nonnull__))
349 : _M_next_bufsiz(__initial_size),
350 _M_upstream(__upstream)
352 _GLIBCXX_DEBUG_ASSERT(__upstream !=
nullptr);
353 _GLIBCXX_DEBUG_ASSERT(__initial_size > 0);
358 __attribute__((__nonnull__(4)))
359 : _M_current_buf(__buffer), _M_avail(__buffer_size),
360 _M_next_bufsiz(_S_next_bufsize(__buffer_size)),
361 _M_upstream(__upstream),
362 _M_orig_buf(__buffer), _M_orig_size(__buffer_size)
364 _GLIBCXX_DEBUG_ASSERT(__upstream !=
nullptr);
365 _GLIBCXX_DEBUG_ASSERT(__buffer !=
nullptr || __buffer_size == 0);
392 _M_release_buffers();
395 if ((_M_current_buf = _M_orig_buf))
397 _M_avail = _M_orig_size;
398 _M_next_bufsiz = _S_next_bufsize(_M_orig_size);
403 _M_next_bufsiz = _M_orig_size;
408 upstream_resource()
const noexcept
409 __attribute__((__returns_nonnull__))
410 {
return _M_upstream; }
414 do_allocate(
size_t __bytes,
size_t __alignment)
override
416 if (__builtin_expect(__bytes == 0,
false))
419 void* __p =
std::align(__alignment, __bytes, _M_current_buf, _M_avail);
420 if (__builtin_expect(__p ==
nullptr,
false))
422 _M_new_buffer(__bytes, __alignment);
423 __p = _M_current_buf;
425 _M_current_buf = (
char*)_M_current_buf + __bytes;
431 do_deallocate(
void*,
size_t,
size_t)
override
436 {
return this == &__other; }
442 _M_new_buffer(
size_t __bytes,
size_t __alignment);
446 _M_release_buffers()
noexcept;
449 _S_next_bufsize(
size_t __buffer_size)
noexcept
451 if (__builtin_expect(__buffer_size == 0,
false))
453 return __buffer_size * _S_growth_factor;
456 static constexpr size_t _S_init_bufsize = 128 *
sizeof(
void*);
457 static constexpr float _S_growth_factor = 1.5;
459 void* _M_current_buf =
nullptr;
461 size_t _M_next_bufsiz = _S_init_bufsize;
465 void*
const _M_orig_buf =
nullptr;
466 size_t const _M_orig_size = _M_next_bufsiz;
469 _Chunk* _M_head =
nullptr;
473_GLIBCXX_END_NAMESPACE_VERSION
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.
memory_resource * new_delete_resource() noexcept
A pmr::memory_resource that uses new to allocate memory.
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 non-thread-safe memory resource that manages pools of fixed-size blocks.
A memory resource that allocates from a fixed-size buffer.