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  *****  */
 /**

Reply via email to