Return-Path: Delivered-To: apmail-httpd-cvs-archive@httpd.apache.org Received: (qmail 32237 invoked by uid 500); 13 Feb 2002 04:49:57 -0000 Mailing-List: contact cvs-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list cvs@httpd.apache.org Received: (qmail 32226 invoked by uid 500); 13 Feb 2002 04:49:57 -0000 Delivered-To: apmail-httpd-2.0-cvs@apache.org Date: 13 Feb 2002 04:49:56 -0000 Message-ID: <20020213044956.94045.qmail@icarus.apache.org> From: brianp@apache.org To: httpd-2.0-cvs@apache.org Subject: cvs commit: httpd-2.0 CHANGES STATUS X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N brianp 02/02/12 20:49:56 Modified: server/mpm/worker fdqueue.h fdqueue.c worker.c . CHANGES STATUS Log: Performance optimization: updated the worker MPM to recycle per-transaction pools instead of destroying them. Based on Ian's benchmark testing, this reduces CPU utilization by about 1% on Solaris. Revision Changes Path 1.11 +6 -2 httpd-2.0/server/mpm/worker/fdqueue.h Index: fdqueue.h =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/worker/fdqueue.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- fdqueue.h 5 Feb 2002 23:13:42 -0000 1.10 +++ fdqueue.h 13 Feb 2002 04:49:55 -0000 1.11 @@ -91,13 +91,17 @@ apr_thread_cond_t *not_empty; apr_thread_cond_t *not_full; int cancel_state; + apr_pool_t **recycled_pools; + int num_recycled; }; typedef struct fd_queue_t fd_queue_t; /* FIXME: APRize these -- return values should be apr_status_t */ int ap_queue_init(fd_queue_t *queue, int queue_capacity, apr_pool_t *a); -int ap_queue_push(fd_queue_t *queue, apr_socket_t *sd, apr_pool_t *p); -apr_status_t ap_queue_pop(fd_queue_t *queue, apr_socket_t **sd, apr_pool_t **p); +int ap_queue_push(fd_queue_t *queue, apr_socket_t *sd, apr_pool_t *p, + apr_pool_t **recycled_pool); +apr_status_t ap_queue_pop(fd_queue_t *queue, apr_socket_t **sd, apr_pool_t **p, + apr_pool_t *recycled_pool); apr_status_t ap_queue_interrupt_all(fd_queue_t *queue); #endif /* FDQUEUE_H */ 1.10 +25 -2 httpd-2.0/server/mpm/worker/fdqueue.c Index: fdqueue.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/worker/fdqueue.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- fdqueue.c 17 Oct 2001 16:29:36 -0000 1.9 +++ fdqueue.c 13 Feb 2002 04:49:55 -0000 1.10 @@ -112,6 +112,10 @@ for (i = 0; i < queue_capacity; ++i) queue->data[i].sd = NULL; + queue->recycled_pools = apr_palloc(a, + queue_capacity * sizeof(apr_pool_t *)); + queue->num_recycled = 0; + apr_pool_cleanup_register(a, queue, ap_queue_destroy, apr_pool_cleanup_null); return FD_QUEUE_SUCCESS; @@ -122,10 +126,12 @@ * the push operation has completed, it signals other threads waiting * in apr_queue_pop() that they may continue consuming sockets. */ -int ap_queue_push(fd_queue_t *queue, apr_socket_t *sd, apr_pool_t *p) +int ap_queue_push(fd_queue_t *queue, apr_socket_t *sd, apr_pool_t *p, + apr_pool_t **recycled_pool) { fd_queue_elem_t *elem; + *recycled_pool = NULL; if (apr_thread_mutex_lock(queue->one_big_mutex) != APR_SUCCESS) { return FD_QUEUE_FAILURE; } @@ -138,6 +144,10 @@ elem->sd = sd; elem->p = p; + if (queue->num_recycled != 0) { + *recycled_pool = queue->recycled_pools[--queue->num_recycled]; + } + apr_thread_cond_signal(queue->not_empty); if (apr_thread_mutex_unlock(queue->one_big_mutex) != APR_SUCCESS) { @@ -153,12 +163,25 @@ * Once retrieved, the socket is placed into the address specified by * 'sd'. */ -apr_status_t ap_queue_pop(fd_queue_t *queue, apr_socket_t **sd, apr_pool_t **p) +apr_status_t ap_queue_pop(fd_queue_t *queue, apr_socket_t **sd, apr_pool_t **p, + apr_pool_t *recycled_pool) { fd_queue_elem_t *elem; if (apr_thread_mutex_lock(queue->one_big_mutex) != APR_SUCCESS) { + if (recycled_pool) { + apr_pool_destroy(recycled_pool); + } return FD_QUEUE_FAILURE; + } + + if (recycled_pool) { + if (queue->num_recycled < queue->bounds) { + queue->recycled_pools[queue->num_recycled++] = recycled_pool; + } + else { + apr_pool_destroy(recycled_pool); + } } /* Keep waiting until we wake up and find that the queue is not empty. */ 1.75 +15 -5 httpd-2.0/server/mpm/worker/worker.c Index: worker.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/worker/worker.c,v retrieving revision 1.74 retrieving revision 1.75 diff -u -r1.74 -r1.75 --- worker.c 11 Feb 2002 23:20:16 -0000 1.74 +++ worker.c 13 Feb 2002 04:49:55 -0000 1.75 @@ -595,6 +595,7 @@ apr_pool_t *tpool = apr_thread_pool_get(thd); void *csd = NULL; apr_pool_t *ptrans; /* Pool for per-transaction stuff */ + apr_pool_t *recycled_pool = NULL; int n; apr_pollfd_t *pollset; apr_status_t rv; @@ -670,9 +671,13 @@ got_fd: if (!workers_may_exit) { /* create a new transaction pool for each accepted socket */ - apr_pool_create_ex(&ptrans, NULL, NULL, APR_POOL_FNEW_ALLOCATOR); + if (recycled_pool == NULL) { + apr_pool_create_ex(&ptrans, NULL, NULL, APR_POOL_FNEW_ALLOCATOR); + } + else { + ptrans = recycled_pool; + } apr_pool_tag(ptrans, "transaction"); - rv = lr->accept_func(&csd, lr, ptrans); if (rv == APR_EGENERAL) { @@ -688,7 +693,8 @@ signal_workers(); } if (csd != NULL) { - rv = ap_queue_push(worker_queue, csd, ptrans); + rv = ap_queue_push(worker_queue, csd, ptrans, + &recycled_pool); if (rv) { /* trash the connection; we couldn't queue the connected * socket to a worker @@ -729,6 +735,7 @@ int process_slot = ti->pid; int thread_slot = ti->tid; apr_socket_t *csd = NULL; + apr_pool_t *last_ptrans = NULL; apr_pool_t *ptrans; /* Pool for per-transaction stuff */ apr_status_t rv; @@ -737,7 +744,9 @@ ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL); while (!workers_may_exit) { ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_READY, NULL); - rv = ap_queue_pop(worker_queue, &csd, &ptrans); + rv = ap_queue_pop(worker_queue, &csd, &ptrans, last_ptrans); + last_ptrans = NULL; + /* We get FD_QUEUE_EINTR whenever ap_queue_pop() has been interrupted * from an explicit call to ap_queue_interrupt_all(). This allows * us to unblock threads stuck in ap_queue_pop() when a shutdown @@ -747,7 +756,8 @@ } process_socket(ptrans, csd, process_slot, thread_slot); requests_this_child--; /* FIXME: should be synchronized - aaron */ - apr_pool_destroy(ptrans); + apr_pool_clear(ptrans); + last_ptrans = ptrans; } ap_update_child_status_from_indexes(process_slot, thread_slot, 1.578 +3 -0 httpd-2.0/CHANGES Index: CHANGES =================================================================== RCS file: /home/cvs/httpd-2.0/CHANGES,v retrieving revision 1.577 retrieving revision 1.578 diff -u -r1.577 -r1.578 --- CHANGES 13 Feb 2002 03:08:10 -0000 1.577 +++ CHANGES 13 Feb 2002 04:49:55 -0000 1.578 @@ -1,5 +1,8 @@ Changes with Apache 2.0.32-dev + *) Performance: Reuse per-connection transaction pools in the + worker MPM, rather than destroying and recreating them. [Brian Pane] + *) mod_negotiation: ForceLanguagePriority now uses 'Prefer' as the default if the directive is not specified. This mirrors older behavior without changes to the httpd.conf. [William Rowe] 1.498 +1 -8 httpd-2.0/STATUS Index: STATUS =================================================================== RCS file: /home/cvs/httpd-2.0/STATUS,v retrieving revision 1.497 retrieving revision 1.498 diff -u -r1.497 -r1.498 --- STATUS 10 Feb 2002 21:16:25 -0000 1.497 +++ STATUS 13 Feb 2002 04:49:55 -0000 1.498 @@ -1,5 +1,5 @@ APACHE 2.0 STATUS: -*-text-*- -Last modified at [$Date: 2002/02/10 21:16:25 $] +Last modified at [$Date: 2002/02/13 04:49:55 $] Release: @@ -185,13 +185,6 @@ gregames says: I see the breakage now, and volunteer to fix it when things calm down a little. It looks OK when there are complete lines and no mime continuations. - - * Modify the worker MPM so that it doesn't need to create and - destroy a pool for each request--possibly by adopting a - leader/follower model in which each worker owns a persistent - ptrans pool (like the prefork MPM) and the workers take - turns acting as listeners...this approach might also help - reduce context-switching * CGI single-byte reads BrianP suggests that this is caused by the ap_scan_script_header_err()