Return-Path: Delivered-To: apmail-apr-dev-archive@apr.apache.org Received: (qmail 41193 invoked by uid 500); 19 Mar 2002 19:40:32 -0000 Mailing-List: contact dev-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Delivered-To: mailing list dev@apr.apache.org Received: (qmail 41181 invoked from network); 19 Mar 2002 19:40:32 -0000 From: "Sander Striker" To: Subject: [PATCH] Maximum free memory in an allocator OR: hifree, revisited Date: Tue, 19 Mar 2002 20:45:38 +0100 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2911.0) X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 Importance: Normal X-Rcpt-To: X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N Hi, Keep getting the question if the hifree patch is going in. So, decided to revisit that patch and implement it now we have the allocators. For those who didn't follow that thread: This patch allows the programmer to set a maximum amount of free bytes allowed on the allocators freelist. Anything over it will be free()d back to the system. Thoughts? Sander Index: include/apr_allocator.h =================================================================== RCS file: /home/cvs/apr/include/apr_allocator.h,v retrieving revision 1.2 diff -u -r1.2 apr_allocator.h --- include/apr_allocator.h 18 Mar 2002 16:24:54 -0000 1.2 +++ include/apr_allocator.h 19 Mar 2002 19:32:41 -0000 @@ -143,6 +143,18 @@ */ APR_DECLARE(apr_pool_t *) apr_allocator_get_owner(apr_allocator_t *allocator); +/** + * Set the maximum amount of free memory to be held by + * the allocator. + * @param allocator The allocator to set the max amount for + * @param size The maximum amount the allocator is allowed + * to keep. + * @remark Passing 0 for size will set the max amount to + * unlimited. + */ +APR_DECLARE(void) apr_allocator_set_max_free(apr_allocator_t *allocator, + apr_size_t size); + #if APR_HAS_THREADS /** * Set a mutex for the allocator to use Index: memory/unix/apr_pools.c =================================================================== RCS file: /home/cvs/apr/memory/unix/apr_pools.c,v retrieving revision 1.163 diff -u -r1.163 apr_pools.c --- memory/unix/apr_pools.c 19 Mar 2002 15:30:07 -0000 1.163 +++ memory/unix/apr_pools.c 19 Mar 2002 19:32:49 -0000 @@ -106,6 +106,8 @@ struct apr_allocator_t { apr_uint32_t max_index; + apr_uint32_t max_free_index; + apr_uint32_t current_free_index; #if APR_HAS_THREADS apr_thread_mutex_t *mutex; #endif /* APR_HAS_THREADS */ @@ -179,6 +181,32 @@ return allocator->owner; } +APR_DECLARE(void) apr_allocator_set_max_free(apr_allocator_t *allocator, + apr_size_t size) +{ + apr_uint32_t max_free_index; + +#if APR_HAS_THREADS + apr_thread_mutex_t *mutex; + + mutex = apr_allocator_get_mutex(allocator); + if (mutex != NULL) + apr_thread_mutex_lock(mutex); +#endif /* APR_HAS_THREADS */ + + max_free_index = APR_ALIGN(size, BOUNDARY_SIZE) >> BOUNDARY_INDEX; + allocator->current_free_index += max_free_index; + allocator->current_free_index -= allocator->max_free_index; + allocator->max_free_index = max_free_index; + if (allocator->current_free_index > max_free_index) + allocator->current_free_index = max_free_index; + +#if APR_HAS_THREADS + if (mutex != NULL) + apr_thread_mutex_unlock(mutex); +#endif +} + APR_INLINE APR_DECLARE(apr_memnode_t *) apr_allocator_alloc(apr_allocator_t *allocator, apr_size_t size) @@ -241,6 +269,10 @@ allocator->max_index = max_index; } + allocator->current_free_index += node->index; + if (allocator->current_free_index > allocator->max_free_index) + allocator->current_free_index = allocator->max_free_index; + #if APR_HAS_THREADS if (allocator->mutex) apr_thread_mutex_unlock(allocator->mutex); @@ -277,6 +309,10 @@ if (node) { *ref = node->next; + allocator->current_free_index += node->index; + if (allocator->current_free_index > allocator->max_free_index) + allocator->current_free_index = allocator->max_free_index; + #if APR_HAS_THREADS if (allocator->mutex) apr_thread_mutex_unlock(allocator->mutex); @@ -312,8 +348,9 @@ APR_DECLARE(void) apr_allocator_free(apr_allocator_t *allocator, apr_memnode_t *node) { - apr_memnode_t *next; + apr_memnode_t *next, *freelist = NULL; apr_uint32_t index, max_index; + apr_uint32_t max_free_index, current_free_index; #if APR_HAS_THREADS if (allocator->mutex) @@ -321,6 +358,8 @@ #endif /* APR_HAS_THREADS */ max_index = allocator->max_index; + max_free_index = allocator->max_free_index; + current_free_index = allocator->current_free_index; /* Walk the list of submitted nodes and free them one by one, * shoving them in the right 'size' buckets as we go. @@ -329,7 +368,12 @@ next = node->next; index = node->index; - if (index < MAX_INDEX) { + if (max_free_index != 0 && index > current_free_index) { + node->next = freelist; + freelist = node; + current_free_index -= index; + } + else if (index < MAX_INDEX) { /* Add the node to the appropiate 'size' bucket. Adjust * the max_index when appropiate. */ @@ -349,11 +393,18 @@ } while ((node = next) != NULL); allocator->max_index = max_index; + allocator->current_free_index = current_free_index; #if APR_HAS_THREADS if (allocator->mutex) apr_thread_mutex_unlock(allocator->mutex); #endif /* APR_HAS_THREADS */ + + while (freelist != NULL) { + node = freelist; + freelist = node->next; + free(node); + } }