32#ifndef _GLIBCXX_MEMORY_RESOURCE
33#define _GLIBCXX_MEMORY_RESOURCE 1
36#pragma GCC system_header
41#define __glibcxx_want_polymorphic_allocator
42#define __glibcxx_want_memory_resource
45#if __cplusplus >= 201703L
72namespace std _GLIBCXX_VISIBILITY(default)
74_GLIBCXX_BEGIN_NAMESPACE_VERSION
78#ifdef __cpp_lib_polymorphic_allocator
79 template<
typename _Tp = std::
byte>
91 [[nodiscard, __gnu__::__returns_nonnull__, __gnu__::__const__]]
96 [[nodiscard, __gnu__::__returns_nonnull__, __gnu__::__const__]]
101 [[__gnu__::__returns_nonnull__]]
106 [[__gnu__::__returns_nonnull__]]
112#if __cpp_lib_memory_resource >= 201603L
113 class synchronized_pool_resource;
138 size_t largest_required_pool_block = 0;
142 class __pool_resource
144 friend class synchronized_pool_resource;
151 __pool_resource(
const __pool_resource&) =
delete;
152 __pool_resource& operator=(
const __pool_resource&) =
delete;
156 allocate(
size_t __bytes,
size_t __alignment);
160 deallocate(
void* __p,
size_t __bytes,
size_t __alignment);
164 void release()
noexcept;
167 {
return _M_unpooled.get_allocator().resource(); }
171 _Pool* _M_alloc_pools();
173 const pool_options _M_opts;
178 _GLIBCXX_STD_C::pmr::vector<_BigBlock> _M_unpooled;
183#if __cpp_lib_memory_resource >= 201603L
190 class synchronized_pool_resource :
public memory_resource
193 synchronized_pool_resource(
const pool_options& __opts,
194 memory_resource* __upstream)
195 __attribute__((__nonnull__));
197 synchronized_pool_resource()
198 : synchronized_pool_resource(pool_options(), get_default_resource())
202 synchronized_pool_resource(memory_resource* __upstream)
203 __attribute__((__nonnull__))
204 : synchronized_pool_resource(pool_options(), __upstream)
208 synchronized_pool_resource(
const pool_options& __opts)
211 synchronized_pool_resource(
const synchronized_pool_resource&) =
delete;
213 virtual ~synchronized_pool_resource();
215 synchronized_pool_resource&
216 operator=(
const synchronized_pool_resource&) =
delete;
221 upstream_resource() const noexcept
222 __attribute__((__returns_nonnull__))
223 {
return _M_impl.resource(); }
225 pool_options options() const noexcept {
return _M_impl._M_opts; }
229 do_allocate(
size_t __bytes,
size_t __alignment)
override;
232 do_deallocate(
void* __p,
size_t __bytes,
size_t __alignment)
override;
235 do_is_equal(
const memory_resource& __other)
const noexcept override
236 {
return this == &__other; }
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;
247 __pool_resource _M_impl;
248 __gthread_key_t _M_key;
250 _TPools* _M_tpools =
nullptr;
251 mutable shared_mutex _M_mx;
261 class unsynchronized_pool_resource :
public memory_resource
264 [[__gnu__::__nonnull__]]
265 unsynchronized_pool_resource(
const pool_options& __opts,
266 memory_resource* __upstream);
268 unsynchronized_pool_resource()
272 [[__gnu__::__nonnull__]]
274 unsynchronized_pool_resource(memory_resource* __upstream)
275 : unsynchronized_pool_resource(
pool_options(), __upstream)
279 unsynchronized_pool_resource(
const pool_options& __opts)
282 unsynchronized_pool_resource(
const unsynchronized_pool_resource&) =
delete;
284 virtual ~unsynchronized_pool_resource();
286 unsynchronized_pool_resource&
287 operator=(
const unsynchronized_pool_resource&) =
delete;
291 [[__gnu__::__returns_nonnull__]]
293 upstream_resource()
const noexcept
294 {
return _M_impl.resource(); }
296 pool_options options()
const noexcept {
return _M_impl._M_opts; }
300 do_allocate(
size_t __bytes,
size_t __alignment)
override;
303 do_deallocate(
void* __p,
size_t __bytes,
size_t __alignment)
override;
306 do_is_equal(
const memory_resource& __other)
const noexcept override
307 {
return this == &__other; }
310 using _Pool = __pool_resource::_Pool;
312 auto _M_find_pool(
size_t)
noexcept;
314 __pool_resource _M_impl;
315 _Pool* _M_pools =
nullptr;
339 class monotonic_buffer_resource :
public memory_resource
343 monotonic_buffer_resource(memory_resource* __upstream)
noexcept
344 __attribute__((__nonnull__))
345 : _M_upstream(__upstream)
346 { _GLIBCXX_DEBUG_ASSERT(__upstream !=
nullptr); }
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)
354 _GLIBCXX_DEBUG_ASSERT(__upstream !=
nullptr);
355 _GLIBCXX_DEBUG_ASSERT(__initial_size > 0);
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)
366 _GLIBCXX_DEBUG_ASSERT(__upstream !=
nullptr);
367 _GLIBCXX_DEBUG_ASSERT(__buffer !=
nullptr || __buffer_size == 0);
370 monotonic_buffer_resource() noexcept
375 monotonic_buffer_resource(
size_t __initial_size) noexcept
379 monotonic_buffer_resource(
void* __buffer,
size_t __buffer_size) noexcept
383 monotonic_buffer_resource(
const monotonic_buffer_resource&) =
delete;
385 virtual ~monotonic_buffer_resource();
387 monotonic_buffer_resource&
388 operator=(
const monotonic_buffer_resource&) =
delete;
394 _M_release_buffers();
397 if ((_M_current_buf = _M_orig_buf))
399 _M_avail = _M_orig_size;
400 _M_next_bufsiz = _S_next_bufsize(_M_orig_size);
405 _M_next_bufsiz = _M_orig_size;
410 upstream_resource()
const noexcept
411 __attribute__((__returns_nonnull__))
412 {
return _M_upstream; }
416 do_allocate(
size_t __bytes,
size_t __alignment)
override
418 if (__builtin_expect(__bytes == 0,
false))
421 void* __p =
std::align(__alignment, __bytes, _M_current_buf, _M_avail);
422 if (__builtin_expect(__p ==
nullptr,
false))
424 _M_new_buffer(__bytes, __alignment);
425 __p = _M_current_buf;
427 _M_current_buf = (
char*)_M_current_buf + __bytes;
433 do_deallocate(
void*,
size_t,
size_t)
override
437 do_is_equal(
const memory_resource& __other)
const noexcept override
438 {
return this == &__other; }
444 _M_new_buffer(
size_t __bytes,
size_t __alignment);
448 _M_release_buffers()
noexcept;
451 _S_next_bufsize(
size_t __buffer_size)
noexcept
453 if (__builtin_expect(__buffer_size == 0,
false))
455 return __buffer_size * _S_growth_factor;
458 static constexpr size_t _S_init_bufsize = 128 *
sizeof(
void*);
459 static constexpr float _S_growth_factor = 1.5;
461 void* _M_current_buf =
nullptr;
463 size_t _M_next_bufsiz = _S_init_bufsize;
466 memory_resource*
const _M_upstream;
467 void*
const _M_orig_buf =
nullptr;
468 size_t const _M_orig_size = _M_next_bufsiz;
471 _Chunk* _M_head =
nullptr;
475_GLIBCXX_END_NAMESPACE_VERSION
memory_resource * set_default_resource(memory_resource *__r) noexcept
Replace the default memory resource pointer.
memory_resource * null_memory_resource() noexcept
A pmr::memory_resource that always throws bad_alloc
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.
Class template polymorphic_allocator.