192 class synchronized_pool_resource :
public memory_resource
196 memory_resource* __upstream)
197 __attribute__((__nonnull__));
199 synchronized_pool_resource()
204 synchronized_pool_resource(memory_resource* __upstream)
205 __attribute__((__nonnull__))
206 : synchronized_pool_resource(
pool_options(), __upstream)
213 synchronized_pool_resource(
const synchronized_pool_resource&) =
delete;
215 virtual ~synchronized_pool_resource();
217 synchronized_pool_resource&
218 operator=(
const synchronized_pool_resource&) =
delete;
223 upstream_resource()
const noexcept
224 __attribute__((__returns_nonnull__))
225 {
return _M_impl.resource(); }
227 pool_options options()
const noexcept {
return _M_impl._M_opts; }
231 do_allocate(
size_t __bytes,
size_t __alignment)
override;
234 do_deallocate(
void* __p,
size_t __bytes,
size_t __alignment)
override;
237 do_is_equal(
const memory_resource& __other)
const noexcept override
238 {
return this == &__other; }
247 auto _M_thread_specific_pools()
noexcept;
249 __pool_resource _M_impl;
250 __gthread_key_t _M_key;
252 _TPools* _M_tpools =
nullptr;
263 class unsynchronized_pool_resource :
public memory_resource
266 [[__gnu__::__nonnull__]]
267 unsynchronized_pool_resource(
const pool_options& __opts,
268 memory_resource* __upstream);
270 unsynchronized_pool_resource()
274 [[__gnu__::__nonnull__]]
276 unsynchronized_pool_resource(memory_resource* __upstream)
277 : unsynchronized_pool_resource(
pool_options(), __upstream)
281 unsynchronized_pool_resource(
const pool_options& __opts)
284 unsynchronized_pool_resource(
const unsynchronized_pool_resource&) =
delete;
286 virtual ~unsynchronized_pool_resource();
288 unsynchronized_pool_resource&
289 operator=(
const unsynchronized_pool_resource&) =
delete;
293 [[__gnu__::__returns_nonnull__]]
295 upstream_resource()
const noexcept
296 {
return _M_impl.resource(); }
298 pool_options options()
const noexcept {
return _M_impl._M_opts; }
302 do_allocate(
size_t __bytes,
size_t __alignment)
override;
305 do_deallocate(
void* __p,
size_t __bytes,
size_t __alignment)
override;
308 do_is_equal(
const memory_resource& __other)
const noexcept override
309 {
return this == &__other; }
312 using _Pool = __pool_resource::_Pool;
314 auto _M_find_pool(
size_t)
noexcept;
316 __pool_resource _M_impl;
317 _Pool* _M_pools =
nullptr;
341 class monotonic_buffer_resource :
public memory_resource
345 monotonic_buffer_resource(memory_resource* __upstream)
noexcept
346 __attribute__((__nonnull__))
347 : _M_upstream(__upstream)
348 { _GLIBCXX_DEBUG_ASSERT(__upstream !=
nullptr); }
350 monotonic_buffer_resource(
size_t __initial_size,
351 memory_resource* __upstream)
noexcept
352 __attribute__((__nonnull__))
353 : _M_next_bufsiz(__initial_size),
354 _M_upstream(__upstream)
356 _GLIBCXX_DEBUG_ASSERT(__upstream !=
nullptr);
357 _GLIBCXX_DEBUG_ASSERT(__initial_size > 0);
360 monotonic_buffer_resource(
void* __buffer,
size_t __buffer_size,
361 memory_resource* __upstream)
noexcept
362 __attribute__((__nonnull__(4)))
363 : _M_current_buf(__buffer), _M_avail(__buffer_size),
364 _M_next_bufsiz(_S_next_bufsize(__buffer_size)),
365 _M_upstream(__upstream),
366 _M_orig_buf(__buffer), _M_orig_size(__buffer_size)
368 _GLIBCXX_DEBUG_ASSERT(__upstream !=
nullptr);
369 _GLIBCXX_DEBUG_ASSERT(__buffer !=
nullptr || __buffer_size == 0);
372 monotonic_buffer_resource() noexcept
377 monotonic_buffer_resource(
size_t __initial_size) noexcept
381 monotonic_buffer_resource(
void* __buffer,
size_t __buffer_size) noexcept
385 monotonic_buffer_resource(
const monotonic_buffer_resource&) =
delete;
387 virtual ~monotonic_buffer_resource();
389 monotonic_buffer_resource&
390 operator=(
const monotonic_buffer_resource&) =
delete;
396 _M_release_buffers();
399 if ((_M_current_buf = _M_orig_buf))
401 _M_avail = _M_orig_size;
402 _M_next_bufsiz = _S_next_bufsize(_M_orig_size);
407 _M_next_bufsiz = _M_orig_size;
412 upstream_resource()
const noexcept
413 __attribute__((__returns_nonnull__))
414 {
return _M_upstream; }
418 do_allocate(
size_t __bytes,
size_t __alignment)
override
420 if (__builtin_expect(__bytes == 0,
false))
423 void* __p =
std::align(__alignment, __bytes, _M_current_buf, _M_avail);
424 if (__builtin_expect(__p ==
nullptr,
false))
426 _M_new_buffer(__bytes, __alignment);
427 __p = _M_current_buf;
429 _M_current_buf = (
char*)_M_current_buf + __bytes;
435 do_deallocate(
void*,
size_t,
size_t)
override
439 do_is_equal(
const memory_resource& __other)
const noexcept override
440 {
return this == &__other; }
446 _M_new_buffer(
size_t __bytes,
size_t __alignment);
450 _M_release_buffers()
noexcept;
453 _S_next_bufsize(
size_t __buffer_size)
noexcept
455 if (__builtin_expect(__buffer_size == 0,
false))
457 return __buffer_size * _S_growth_factor;
460 static constexpr size_t _S_init_bufsize = 128 *
sizeof(
void*);
461 static constexpr float _S_growth_factor = 1.5;
463 void* _M_current_buf =
nullptr;
465 size_t _M_next_bufsiz = _S_init_bufsize;
468 memory_resource*
const _M_upstream;
469 void*
const _M_orig_buf =
nullptr;
470 size_t const _M_orig_size = _M_next_bufsiz;
473 _Chunk* _M_head =
nullptr;