apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Sander Striker" <stri...@apache.org>
Subject [PATCH] Free memory over a certain threshold back to the system
Date Wed, 06 Feb 2002 12:24:36 GMT
Hi,

The 'high free' patch.  I'm not sure we want this.
It may hide pools abuse problems.

Sander


Index: memory/unix/apr_pools.c
===================================================================
RCS file: /home/cvs/apr/memory/unix/apr_pools.c,v
retrieving revision 1.149
diff -u -r1.149 apr_pools.c
--- memory/unix/apr_pools.c	5 Feb 2002 12:09:43 -0000	1.149
+++ memory/unix/apr_pools.c	6 Feb 2002 11:39:52 -0000
@@ -92,13 +92,19 @@
  * Magic numbers
  */
 
-#define MIN_ALLOC 8192
-#define MAX_INDEX   20
+#define MIN_ALLOC      8192
+#define MAX_INDEX      20
 
+/* New nodes are rounded up to the next BOUNDARY_SIZE (4096) */
 #define BOUNDARY_INDEX 12
 #define BOUNDARY_SIZE (1 << BOUNDARY_INDEX)
 
- 
+/* Free blocks when the total number of free bytes goes
+ * over DEFAULT_MAX_FREE * BOUNDARY_SIZE (2MB)
+ */
+#define DEFAULT_MAX_FREE 512
+
+
 /*
  * Macros and defines
  */
@@ -129,6 +135,7 @@
 
 struct allocator_t {
     apr_uint32_t        max_index;
+    apr_uint32_t        max_free;
 #if APR_HAS_THREADS
     apr_thread_mutex_t *mutex;
 #endif
@@ -206,12 +213,13 @@
 
 #if !APR_POOL_DEBUG
 static allocator_t  global_allocator = { 
-    0,          /* max_index */
+    0,                /* max_index */
+    DEFAULT_MAX_FREE, /* max_free */
 #if APR_HAS_THREADS
-    NULL,       /* mutex */
-#endif
-    NULL,       /* owner */
-    { NULL }    /* free[0] */
+    NULL,             /* mutex */
+#endif /* APR_HAS_THREADS */
+    NULL,             /* owner */
+    { NULL }          /* free[0] */
 };
 #endif /* !APR_POOL_DEBUG */
 
@@ -241,6 +249,7 @@
         return APR_SUCCESS;
     
     memset(&global_allocator, 0, SIZEOF_ALLOCATOR_T);
+    global_allocator.max_free = DEFAULT_MAX_FREE;
 
     if ((rv = apr_pool_create_ex(&global_pool, NULL, NULL, APR_POOL_FDEFAULT)) != APR_SUCCESS)
{
         return rv;
@@ -355,6 +364,8 @@
                 allocator->max_index = max_index;
             }
 
+            allocator->max_free += node->index;
+            
 #if APR_HAS_THREADS
             if (allocator->mutex)
                 apr_thread_mutex_unlock(allocator->mutex);
@@ -391,6 +402,8 @@
         if (node) {
             *ref = node->next;
 
+            allocator->max_free += node->index;
+            
 #if APR_HAS_THREADS
             if (allocator->mutex)
                 apr_thread_mutex_unlock(allocator->mutex);
@@ -424,8 +437,8 @@
 
 static APR_INLINE void node_free(allocator_t *allocator, node_t *node)
 {
-    node_t *next;
-    apr_uint32_t index, max_index;
+    node_t *next, *free_nodes = NULL;
+    apr_uint32_t index, max_index, max_free;
 
 #if APR_HAS_THREADS
     if (allocator->mutex)
@@ -433,6 +446,7 @@
 #endif
 
     max_index = allocator->max_index;
+    max_free = allocator->max_free;
 
     /* Walk the list of submitted nodes and free them one by one,
      * shoving them in the right 'size' buckets as we go.
@@ -441,31 +455,47 @@
         next = node->next;
         index = node->index;
 
-        if (index < MAX_INDEX) {
-            /* Add the node to the appropiate 'size' bucket.  Adjust
-             * the max_index when appropiate.
-             */
-            if ((node->next = allocator->free[index]) == NULL && index >
max_index) {
-                 max_index = index;
-            }
-            allocator->free[index] = node;
+        if (max_free < index) {
+            node->next = free_nodes;
+            free_nodes = node;
         }
         else {
-            /* This node is too large to keep in a specific size bucket,
-             * just add it to the sink (at index 0).
-             */
-            node->next = allocator->free[0];
-            allocator->free[0] = node;
+            max_free -= index;
+            
+            if (index < MAX_INDEX) {
+                /* Add the node to the appropiate 'size' bucket.  Adjust
+                 * the max_index when appropiate.
+                 */
+                if ((node->next = allocator->free[index]) == NULL 
+                    && index > max_index) {
+                    max_index = index;
+                }
+                allocator->free[index] = node;
+            }
+            else {
+                /* This node is too large to keep in a specific size bucket,
+                 * just add it to the sink (at index 0).
+                 */
+                node->next = allocator->free[0];
+                allocator->free[0] = node;
+            }
         }
     }
     while ((node = next) != NULL);
 
     allocator->max_index = max_index;
+    allocator->max_free = max_free;
 
 #if APR_HAS_THREADS
     if (allocator->mutex)
         apr_thread_mutex_unlock(allocator->mutex);
 #endif
+
+    while (free_nodes != NULL) {
+        node = free_nodes;
+        free_nodes = node->next;
+        free(node);
+    }
 }
 
 APR_DECLARE(void *) apr_palloc(apr_pool_t *pool, apr_size_t size)
@@ -682,6 +712,7 @@
         
         memset(new_allocator, 0, SIZEOF_ALLOCATOR_T);
         new_allocator->owner = pool;
+        new_allocator->max_free = DEFAULT_MAX_FREE;
 
         pool->allocator = new_allocator;
         pool->active = pool->self = node;

Mime
View raw message