apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bill Stoddard" <b...@wstoddard.com>
Subject Re: [PATCH] Maximum free memory in an allocator OR: hifree, revisited
Date Tue, 19 Mar 2002 20:36:06 GMT
This could be quite useful for mod_*_cache.  What triggers the free?

Bill
----- Original Message ----- 
From: "Sander Striker" <striker@apache.org>
To: <dev@apr.apache.org>
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);
> +    }
>  }
> 

Mime
View raw message