apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Sander Striker" <stri...@apache.org>
Subject [PATCH] Maximum free memory in an allocator OR: hifree, revisited
Date Tue, 19 Mar 2002 19:45:38 GMT
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