This could be quite useful for mod_*_cache. What triggers the free?
Bill
----- Original Message -----
From: "Sander Striker" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Tuesday, March 19, 2002 2:45 PM
Subject: [PATCH] Maximum free memory in an allocator OR: hifree, revisited
> 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);
> + }
> }
>