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;