striker 02/05/26 01:52:02
Modified: include apr_allocator.h
memory/unix apr_pools.c
Log:
The hi free patch. This will add the ability for a developer to
set a maximum on the free blocks in an allocators freelist.
See: <[EMAIL PROTECTED]> for why we need it.
And: <[EMAIL PROTECTED]> for a
benchmark showing it doesn't affect httpd performance.
Revision Changes Path
1.5 +10 -0 apr/include/apr_allocator.h
Index: apr_allocator.h
===================================================================
RCS file: /home/cvs/apr/include/apr_allocator.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- apr_allocator.h 9 Apr 2002 06:56:55 -0000 1.4
+++ apr_allocator.h 26 May 2002 08:52:01 -0000 1.5
@@ -151,6 +151,16 @@
*/
APR_DECLARE(apr_pool_t *) apr_allocator_get_owner(apr_allocator_t
*allocator);
+
+/**
+ * Set the current threshold at which the allocator should start
+ * giving blocks back to the system.
+ * @param allocator The allocator the set the threshold on
+ * @param size The threshold. 0 == unlimited.
+ */
+APR_DECLARE(void) apr_allocator_set_max_free(apr_allocator_t *allocator,
+ apr_size_t size);
+
#include "apr_thread_mutex.h"
#if APR_HAS_THREADS
1.168 +54 -2 apr/memory/unix/apr_pools.c
Index: apr_pools.c
===================================================================
RCS file: /home/cvs/apr/memory/unix/apr_pools.c,v
retrieving revision 1.167
retrieving revision 1.168
diff -u -r1.167 -r1.168
--- apr_pools.c 5 May 2002 22:24:41 -0000 1.167
+++ apr_pools.c 26 May 2002 08:52:02 -0000 1.168
@@ -93,6 +93,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 */
@@ -166,6 +168,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)
@@ -228,6 +256,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);
@@ -264,6 +296,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);
@@ -299,8 +335,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)
@@ -308,6 +345,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.
@@ -316,7 +355,11 @@
next = node->next;
index = node->index;
- if (index < MAX_INDEX) {
+ if (max_free_index != 0 && index > current_free_index) {
+ node->next = freelist;
+ freelist = node;
+ }
+ else if (index < MAX_INDEX) {
/* Add the node to the appropiate 'size' bucket. Adjust
* the max_index when appropiate.
*/
@@ -325,6 +368,7 @@
max_index = index;
}
allocator->free[index] = node;
+ current_free_index -= index;
}
else {
/* This node is too large to keep in a specific size bucket,
@@ -332,15 +376,23 @@
*/
node->next = allocator->free[0];
allocator->free[0] = node;
+ current_free_index -= index;
}
} 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);
+ }
}