summaryrefslogtreecommitdiff
path: root/memory/unix/apr_pools.c
diff options
context:
space:
mode:
authorsf <sf@13f79535-47bb-0310-9956-ffa450edef68>2014-05-14 21:30:48 +0000
committersf <sf@13f79535-47bb-0310-9956-ffa450edef68>2014-05-14 21:30:48 +0000
commit2b53ade052014def1455c512fe7d5283fd344bc7 (patch)
tree454b56ef49820bd0f509719ce61b2577e53f509d /memory/unix/apr_pools.c
parent968eeaaf7dcfce3141ced68c9a38ee889451e0f8 (diff)
downloadlibapr-2b53ade052014def1455c512fe7d5283fd344bc7.tar.gz
Don't waste memory when creating or allocating from small, long-lived
APR pools after clearing or destroying pools that allocated larger nodes. When allocating nodes from the bucket allocator (<= 80k or 20 pages), we would eagerly reuse *any* free node that is at least the minimum size. Depending on the pool usage scheme, that extra memory would never be used. This patch limits the node to approximate twice the minimum. * memory/unix/apr_pools.c (allocator_alloc): When searching the buckets for free nodes, limit the range to twice the starting index. Submitted by: Stefan Fuhrmann <stefan fuhrmann wandisco com> git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@1594729 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'memory/unix/apr_pools.c')
-rw-r--r--memory/unix/apr_pools.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/memory/unix/apr_pools.c b/memory/unix/apr_pools.c
index cd4ae112d..da33c78da 100644
--- a/memory/unix/apr_pools.c
+++ b/memory/unix/apr_pools.c
@@ -239,7 +239,7 @@ static APR_INLINE
apr_memnode_t *allocator_alloc(apr_allocator_t *allocator, apr_size_t in_size)
{
apr_memnode_t *node, **ref;
- apr_uint32_t max_index;
+ apr_uint32_t max_index, upper_index;
apr_size_t size, i, index;
/* Round up the block size to the next boundary, but always
@@ -273,6 +273,11 @@ apr_memnode_t *allocator_alloc(apr_allocator_t *allocator, apr_size_t in_size)
/* Walk the free list to see if there are
* any nodes on it of the requested size
*
+ * If there is no exact match, look for nodes
+ * of up to twice the requested size, so we
+ * won't unnecessarily allocate more memory
+ * nor waste too much of what we have.
+ *
* NOTE: an optimization would be to check
* allocator->free[index] first and if no
* node is present, directly use
@@ -281,9 +286,10 @@ apr_memnode_t *allocator_alloc(apr_allocator_t *allocator, apr_size_t in_size)
* memory waste.
*/
max_index = allocator->max_index;
+ upper_index = 2 * index < max_index ? 2 * index : max_index;
ref = &allocator->free[index];
i = index;
- while (*ref == NULL && i < max_index) {
+ while (*ref == NULL && i < upper_index) {
ref++;
i++;
}