On Sun, 31 Mar 2002, Brian Pane wrote: > requests/second > --------------- > Test 2.0.34 2.0.34 + 2.0.34 + > file baseline Brian's patch Cliff's patch > 50k.shtml 654 667 686 > incl.shtml 1870 1992 2007
Sweet!! In both cases this is really great news. PS: I remembered at lunch that there was a buglet in apr_bucket_alloc_destroy() I'd forgotten to fix. Since list itself is allocated from list->allocator, we need to save a pointer to the allocator before we call apr_allocator_free() so that we will still have a valid pointer to pass to apr_allocator_destroy() afterward. Attached is a revised patch. --Cliff -------------------------------------------------------------- Cliff Woolley [EMAIL PROTECTED] Charlottesville, VA
? config.nice-prefork ? config.nice-worker Index: include/http_core.h =================================================================== RCS file: /home/cvs/httpd-2.0/include/http_core.h,v retrieving revision 1.64 diff -u -d -r1.64 http_core.h --- include/http_core.h 20 Mar 2002 02:05:42 -0000 1.64 +++ include/http_core.h 31 Mar 2002 20:38:58 -0000 @@ -129,9 +129,9 @@ #define SATISFY_ANY 1 #define SATISFY_NOSPEC 2 -/* Make sure we don't write less than 8192 bytes at any one time. +/* Make sure we don't write less than 8000 bytes at any one time. */ -#define AP_MIN_BYTES_TO_WRITE 8192 +#define AP_MIN_BYTES_TO_WRITE 8000 /** * Retrieve the value of Options for this request Index: srclib/apr/include/apr_allocator.h =================================================================== RCS file: /home/cvs/apr/include/apr_allocator.h,v retrieving revision 1.2 diff -u -d -r1.2 apr_allocator.h --- srclib/apr/include/apr_allocator.h 18 Mar 2002 16:24:54 -0000 1.2 +++ srclib/apr/include/apr_allocator.h 31 Mar 2002 20:38:58 -0000 @@ -85,6 +85,15 @@ /** the structure which holds information about the allocation */ typedef struct apr_memnode_t apr_memnode_t; +struct apr_memnode_t { + apr_memnode_t *next; + apr_uint32_t index; + char *first_avail; + char *endp; +}; + +#define APR_MEMNODE_T_SIZE APR_ALIGN_DEFAULT(sizeof(apr_memnode_t)) + /** * Create a new allocator * @param allocator The allocator we have just created. Index: srclib/apr/memory/unix/apr_pools.c =================================================================== RCS file: /home/cvs/apr/memory/unix/apr_pools.c,v retrieving revision 1.164 diff -u -d -r1.164 apr_pools.c --- srclib/apr/memory/unix/apr_pools.c 31 Mar 2002 10:12:21 -0000 1.164 +++ srclib/apr/memory/unix/apr_pools.c 31 Mar 2002 20:38:58 -0000 @@ -77,19 +77,6 @@ /* - * XXX: Memory node struct, move to private header file - */ -struct apr_memnode_t { - apr_memnode_t *next; - apr_uint32_t index; - char *first_avail; - char *endp; -}; - -#define SIZEOF_MEMNODE_T APR_ALIGN_DEFAULT(sizeof(apr_memnode_t)) - - -/* * Magic numbers */ @@ -189,7 +176,7 @@ /* Round up the block size to the next boundary, but always * allocate at least a certain size (MIN_ALLOC). */ - size = APR_ALIGN(size + SIZEOF_MEMNODE_T, BOUNDARY_SIZE); + size = APR_ALIGN(size + APR_MEMNODE_T_SIZE, BOUNDARY_SIZE); if (size < MIN_ALLOC) size = MIN_ALLOC; @@ -247,7 +234,7 @@ #endif /* APR_HAS_THREADS */ node->next = NULL; - node->first_avail = (char *)node + SIZEOF_MEMNODE_T; + node->first_avail = (char *)node + APR_MEMNODE_T_SIZE; return node; } @@ -283,7 +270,7 @@ #endif /* APR_HAS_THREADS */ node->next = NULL; - node->first_avail = (char *)node + SIZEOF_MEMNODE_T; + node->first_avail = (char *)node + APR_MEMNODE_T_SIZE; return node; } @@ -302,7 +289,7 @@ node->next = NULL; node->index = index; - node->first_avail = (char *)node + SIZEOF_MEMNODE_T; + node->first_avail = (char *)node + APR_MEMNODE_T_SIZE; node->endp = (char *)node + size; return node; @@ -721,7 +708,7 @@ allocator = parent->allocator; if ((node = apr_allocator_alloc(allocator, - MIN_ALLOC - SIZEOF_MEMNODE_T)) == NULL) { + MIN_ALLOC - APR_MEMNODE_T_SIZE)) == NULL) { if (abort_fn) abort_fn(APR_ENOMEM); Index: srclib/apr-util/buckets/apr_buckets_alloc.c =================================================================== RCS file: /home/cvs/apr-util/buckets/apr_buckets_alloc.c,v retrieving revision 1.4 diff -u -d -r1.4 apr_buckets_alloc.c --- srclib/apr-util/buckets/apr_buckets_alloc.c 30 Mar 2002 12:43:07 -0000 1.4 +++ srclib/apr-util/buckets/apr_buckets_alloc.c 31 Mar 2002 20:38:59 -0000 @@ -52,32 +52,100 @@ * <http://www.apache.org/>. */ -#include <stdlib.h> #include "apr_buckets.h" +#include "apr_allocator.h" -/* - * XXX: this file will be filled in later - */ +#define ALLOC_AMT (8192 - APR_MEMNODE_T_SIZE) + +typedef struct node_header_t { + apr_size_t size; + apr_bucket_alloc_t *alloc; + apr_memnode_t *memnode; + struct node_header_t *next; +} node_header_t; + +#define SIZEOF_NODE_HEADER_T APR_ALIGN_DEFAULT(sizeof(node_header_t)) +/** A list of free memory from which new buckets or private bucket + * structures can be allocated. + */ struct apr_bucket_alloc_t { - int x; /* temporary... some compilers trigger an error on empty structure defs */ + apr_allocator_t *allocator; + node_header_t *freelist; + apr_memnode_t *blocks; }; APU_DECLARE(apr_bucket_alloc_t *) apr_bucket_alloc_create(apr_pool_t *p) { - return (apr_bucket_alloc_t *)0xFECCFECC; + apr_allocator_t *allocator; + apr_bucket_alloc_t *list; + apr_memnode_t *block; + + apr_allocator_create(&allocator); + block = apr_allocator_alloc(allocator, ALLOC_AMT); + list = (apr_bucket_alloc_t *)block->first_avail; + list->allocator = allocator; + list->freelist = NULL; + list->blocks = block; + block->first_avail += APR_ALIGN_DEFAULT(sizeof(*list)); + return list; } APU_DECLARE(void) apr_bucket_alloc_destroy(apr_bucket_alloc_t *list) { + apr_allocator_t *allocator = list->allocator; + + apr_allocator_free(allocator, list->blocks); + apr_allocator_destroy(allocator); } APU_DECLARE(void *) apr_bucket_alloc(apr_size_t size, apr_bucket_alloc_t *list) { - return malloc(size); + node_header_t *node; + apr_memnode_t *active = list->blocks; + char *endp; + + size += SIZEOF_NODE_HEADER_T; + if (size <= APR_BUCKET_ALLOC_SIZE) { + if (list->freelist) { + node = list->freelist; + list->freelist = node->next; + } + else { + endp = active->first_avail + APR_BUCKET_ALLOC_SIZE; + if (endp >= active->endp) { + list->blocks = apr_allocator_alloc(list->allocator, ALLOC_AMT); + list->blocks->next = active; + active = list->blocks; + endp = active->first_avail + APR_BUCKET_ALLOC_SIZE; + } + node = (node_header_t *)active->first_avail; + node->alloc = list; + node->memnode = active; + node->size = APR_BUCKET_ALLOC_SIZE; + active->first_avail = endp; + } + } + else { + apr_memnode_t *memnode = apr_allocator_alloc(list->allocator, size); + node = (node_header_t *)memnode->first_avail; + node->alloc = list; + node->memnode = memnode; + node->size = size; + } + return ((char *)node) + SIZEOF_NODE_HEADER_T; } -APU_DECLARE(void) apr_bucket_free(void *block) +APU_DECLARE(void) apr_bucket_free(void *mem) { - free(block); + node_header_t *node = (node_header_t *)((char *)mem - SIZEOF_NODE_HEADER_T); + apr_bucket_alloc_t *list = node->alloc; + + if (node->size == APR_BUCKET_ALLOC_SIZE) { + node->next = list->freelist; + list->freelist = node; + } + else { + apr_allocator_free(list->allocator, node->memnode); + } } Index: srclib/apr-util/include/apr_buckets.h =================================================================== RCS file: /home/cvs/apr-util/include/apr_buckets.h,v retrieving revision 1.133 diff -u -d -r1.133 apr_buckets.h --- srclib/apr-util/include/apr_buckets.h 29 Mar 2002 08:12:08 -0000 1.133 +++ srclib/apr-util/include/apr_buckets.h 31 Mar 2002 20:38:59 -0000 @@ -84,8 +84,8 @@ * @{ */ -/** default bucket buffer size */ -#define APR_BUCKET_BUFF_SIZE 8192 +/** default bucket buffer size - 8KB minus room for memory allocator headers */ +#define APR_BUCKET_BUFF_SIZE 8000 typedef enum { APR_BLOCK_READ, /* block until data becomes available */ @@ -613,6 +613,28 @@ * be created while reading from this file bucket */ apr_pool_t *readpool; }; + +typedef union apr_bucket_structs apr_bucket_structs; +/** + * A union of all bucket structures so we know what + * the max size is. + */ +union apr_bucket_structs { + apr_bucket b; + apr_bucket_heap heap; + apr_bucket_pool pool; +#if APR_HAS_MMAP + apr_bucket_mmap mmap; +#endif + apr_bucket_file file; +}; + +/** + * The amount that apr_bucket_alloc() should allocate in the common case. + * Note: this is twice as big as apr_bucket_structs to allow breathing + * room for third-party bucket types and the bucket allocator. + */ +#define APR_BUCKET_ALLOC_SIZE APR_ALIGN_DEFAULT(2*sizeof(apr_bucket_structs)) /* ***** Bucket Brigade Functions ***** */ /**