From 36d2acbd78eaa275797be9f7dfd3f7bd1b010646 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 21 Nov 2018 18:40:55 +0000 Subject: [PATCH] PR libstdc++/88111 Make maximum block size depend on size_t width PR libstdc++/88111 * include/std/memory_resource (pool_options): Add Doxygen comments. * src/c++17/memory_resource.cc (pool_sizes): Only use suitable values on targets with 16-bit or 20-bit size_t type. (munge_options): Make default values depend on width of size_t type. From-SVN: r266353 --- libstdc++-v3/ChangeLog | 6 ++++++ libstdc++-v3/include/std/memory_resource | 14 +++++++++++++- libstdc++-v3/src/c++17/memory_resource.cc | 23 ++++++++++++++++++----- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index aaf17591726..0ad33dac1ba 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,11 @@ 2018-11-21 Jonathan Wakely + PR libstdc++/88111 + * include/std/memory_resource (pool_options): Add Doxygen comments. + * src/c++17/memory_resource.cc (pool_sizes): Only use suitable values + on targets with 16-bit or 20-bit size_t type. + (munge_options): Make default values depend on width of size_t type. + PR libstdc++/88113 * src/c++17/memory_resource.cc (bitset::size_type): Use the smaller of uint32_t and size_t. diff --git a/libstdc++-v3/include/std/memory_resource b/libstdc++-v3/include/std/memory_resource index 87ad25d60f3..e9a46a3b455 100644 --- a/libstdc++-v3/include/std/memory_resource +++ b/libstdc++-v3/include/std/memory_resource @@ -299,13 +299,25 @@ namespace pmr { return !(__a == __b); } + /// Parameters for tuning a pool resource's behaviour. struct pool_options { + /** @brief Upper limit on number of blocks in a chunk. + * + * A lower value prevents allocating huge chunks that could remain mostly + * unused, but means pools will need to replenished more frequently. + */ size_t max_blocks_per_chunk = 0; + + /* @brief Largest block size (in bytes) that should be served from pools. + * + * Larger allocations will be served directly by the upstream resource, + * not from one of the pools managed by the pool resource. + */ size_t largest_required_pool_block = 0; }; - // Common implementation details for unsynchronized/synchronized pool resources. + // Common implementation details for un-/synchronized pool resources. class __pool_resource { friend class synchronized_pool_resource; diff --git a/libstdc++-v3/src/c++17/memory_resource.cc b/libstdc++-v3/src/c++17/memory_resource.cc index 6198e6b68ca..929df93233c 100644 --- a/libstdc++-v3/src/c++17/memory_resource.cc +++ b/libstdc++-v3/src/c++17/memory_resource.cc @@ -825,10 +825,15 @@ namespace pmr 128, 192, 256, 320, 384, 448, 512, 768, +#if __SIZE_WIDTH__ > 16 1024, 1536, 2048, 3072, - 1<<12, 1<<13, 1<<14, 1<<15, 1<<16, 1<<17, +#if __SIZE_WIDTH__ > 20 + 1<<12, 1<<13, 1<<14, + 1<<15, 1<<16, 1<<17, 1<<20, 1<<21, 1<<22 // 4MB should be enough for anybody +#endif +#endif }; pool_options @@ -839,10 +844,13 @@ namespace pmr // replaced with implementation-defined defaults, and sizes may be // rounded to unspecified granularity. - // Absolute maximum. Each pool might have a smaller maximum. + // max_blocks_per_chunk sets the absolute maximum for the pool resource. + // Each pool might have a smaller maximum, because pools for very large + // objects might impose smaller limit. if (opts.max_blocks_per_chunk == 0) { - opts.max_blocks_per_chunk = 1024 * 10; // TODO a good default? + // Pick a default that depends on the number of bits in size_t. + opts.max_blocks_per_chunk = __SIZE_WIDTH__ << 8; } else { @@ -854,10 +862,15 @@ namespace pmr opts.max_blocks_per_chunk = chunk::max_blocks_per_chunk(); } - // Absolute minimum. Likely to be much larger in practice. + // largest_required_pool_block specifies the largest block size that will + // be allocated from a pool. Larger allocations will come directly from + // the upstream resource and so will not be pooled. if (opts.largest_required_pool_block == 0) { - opts.largest_required_pool_block = 4096; // TODO a good default? + // Pick a sensible default that depends on the number of bits in size_t + // (pools with larger block sizes must be explicitly requested by + // using a non-zero value for largest_required_pool_block). + opts.largest_required_pool_block = __SIZE_WIDTH__ << 6; } else {