Received: (from majordom@localhost) by hyperreal.com (8.8.5/8.8.5) id OAA27326; Mon, 30 Jun 1997 14:18:16 -0700 (PDT) Received: (from dgaudet@localhost) by hyperreal.com (8.8.5/8.8.5) id OAA27317 for apache-cvs; Mon, 30 Jun 1997 14:18:13 -0700 (PDT) Date: Mon, 30 Jun 1997 14:18:13 -0700 (PDT) From: Dean Gaudet Message-Id: <199706302118.OAA27317@hyperreal.com> To: apache-cvs@hyperreal.com Subject: cvs commit: apache/src CHANGES http_config.c Sender: apache-cvs-owner@apache.org Precedence: bulk Reply-To: new-httpd@apache.org dgaudet 97/06/30 14:18:13 Modified: src CHANGES http_config.c Log: run_method optimized to avoid needless scanning over NULLs in the module list Revision Changes Path 1.314 +4 -1 apache/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache/src/CHANGES,v retrieving revision 1.313 retrieving revision 1.314 diff -C3 -r1.313 -r1.314 *** CHANGES 1997/06/30 21:09:56 1.313 --- CHANGES 1997/06/30 21:18:10 1.314 *************** *** 1,5 **** Changes with Apache 1.3 ! *) Revamp of (unix) scoreboard management code such that it avoids unnecessary traversals of the scoreboard on each hit. This is particularly important for high volume sites with a large --- 1,8 ---- Changes with Apache 1.3 ! ! *) run_method optimized to avoid needless scanning over NULLs in the ! module list. [Dean Gaudet] ! *) Revamp of (unix) scoreboard management code such that it avoids unnecessary traversals of the scoreboard on each hit. This is particularly important for high volume sites with a large 1.55 +99 -16 apache/src/http_config.c Index: http_config.c =================================================================== RCS file: /export/home/cvs/apache/src/http_config.c,v retrieving revision 1.54 retrieving revision 1.55 diff -C3 -r1.54 -r1.55 *** http_config.c 1997/06/29 19:05:20 1.54 --- http_config.c 1997/06/30 21:18:11 1.55 *************** *** 144,150 **** void * merge_per_dir_configs (pool *p, void *base, void *new) { ! void **conf_vector = (void **)pcalloc(p, sizeof(void*) * total_modules); void **base_vector = (void **) base; void **new_vector = (void **) new; module *modp; --- 144,150 ---- void * merge_per_dir_configs (pool *p, void *base, void *new) { ! void **conf_vector = (void **)palloc(p, sizeof(void*) * total_modules); void **base_vector = (void **) base; void **new_vector = (void **) new; module *modp; *************** *** 250,269 **** * do the dirty work of slogging through the module structures. */ ! int run_method (request_rec *r, int offset, int run_all) { ! module *modp; ! for (modp = top_module; modp; modp = modp->next) { ! handler mod_handler = *(handler *)(offset + (char *)(modp)); ! if (mod_handler) { int result; - Explain1("Run %s",ShowMethod(modp,offset)); result = (*mod_handler)(r); - Explain2("%s returned %d",ShowMethod(modp,offset),result); if (result != DECLINED && (!run_all || result != OK)) return result; } --- 250,350 ---- * do the dirty work of slogging through the module structures. */ ! /* ! * Optimized run_method routines. The observation here is that many modules ! * have NULL for most of the methods. So we build optimized lists of ! * everything. If you think about it, this is really just like a sparse array ! * implementation to avoid scanning the zero entries. ! */ ! static const int method_offsets[] = { ! XtOffsetOf (module, translate_handler), ! XtOffsetOf (module, check_user_id), ! XtOffsetOf (module, auth_checker), ! XtOffsetOf (module, access_checker), ! XtOffsetOf (module, type_checker), ! XtOffsetOf (module, fixer_upper), ! XtOffsetOf (module, logger), ! XtOffsetOf (module, header_parser) ! }; ! #define NMETHODS (sizeof (method_offsets)/sizeof (method_offsets[0])) ! ! static struct { ! int translate_handler; ! int check_user_id; ! int auth_checker; ! int access_checker; ! int type_checker; ! int fixer_upper; ! int logger; ! int header_parser; ! } offsets_into_method_ptrs; ! ! /* ! * This is just one big array of method_ptrs. It's constructed such that, ! * for example, method_ptrs[ offsets_into_method_ptrs.logger ] is the first ! * logger function. You go one-by-one from there until you hit a NULL. ! * This structure was designed to hopefully maximize cache-coolness. ! */ ! static handler *method_ptrs; ! ! /* routine to reconstruct all these shortcuts... called after every ! * add_module. ! * XXX: this breaks if modules dink with their methods pointers ! */ ! static void ! build_method_shortcuts (void) ! { ! module *modp; ! int how_many_ptrs; ! int i; ! int next_ptr; ! handler fp; ! ! if (method_ptrs) { ! /* free up any previous set of method_ptrs */ ! free (method_ptrs); ! } ! ! /* first we count how many functions we have */ ! how_many_ptrs = 0; ! for (modp = top_module; modp; modp = modp->next) { ! for (i = 0; inext) { ! fp = *(handler *)(method_offsets[i] + (char *)modp); ! if (fp) { ! method_ptrs[next_ptr++] = fp; ! } ! } ! method_ptrs[next_ptr++] = NULL; ! } ! } ! ! ! static int run_method (request_rec *r, int offset, int run_all) { ! int i; ! ! for (i = offset; method_ptrs[i]; ++i ) { ! handler mod_handler = method_ptrs[i]; ! if (mod_handler) { int result; result = (*mod_handler)(r); if (result != DECLINED && (!run_all || result != OK)) return result; } *************** *** 273,299 **** } int translate_name(request_rec *r) { ! return run_method (r, XtOffsetOf (module, translate_handler), 0); } int check_access(request_rec *r) { ! return run_method (r, XtOffsetOf (module, access_checker), 1); } int find_types (request_rec *r) { ! return run_method (r, XtOffsetOf (module, type_checker), 0); } int run_fixups (request_rec *r) { ! return run_method (r, XtOffsetOf (module, fixer_upper), 1); } int log_transaction (request_rec *r) { ! return run_method (r, XtOffsetOf (module, logger), 1); } int header_parse (request_rec *r) { ! return run_method (r, XtOffsetOf (module, header_parser), 1); } /* Auth stuff --- anything that defines one of these will presumably --- 354,380 ---- } int translate_name(request_rec *r) { ! return run_method (r, offsets_into_method_ptrs.translate_handler, 0); } int check_access(request_rec *r) { ! return run_method (r, offsets_into_method_ptrs.access_checker, 1); } int find_types (request_rec *r) { ! return run_method (r, offsets_into_method_ptrs.type_checker, 0); } int run_fixups (request_rec *r) { ! return run_method (r, offsets_into_method_ptrs.fixer_upper, 1); } int log_transaction (request_rec *r) { ! return run_method (r, offsets_into_method_ptrs.logger, 1); } int header_parse (request_rec *r) { ! return run_method (r, offsets_into_method_ptrs.header_parser, 1); } /* Auth stuff --- anything that defines one of these will presumably *************** *** 302,312 **** */ int check_user_id (request_rec *r) { ! return run_method (r, XtOffsetOf (module, check_user_id), 0); } int check_auth (request_rec *r) { ! return run_method (r, XtOffsetOf (module, auth_checker), 0); } int invoke_handler (request_rec *r) --- 383,393 ---- */ int check_user_id (request_rec *r) { ! return run_method (r, offsets_into_method_ptrs.check_user_id, 0); } int check_auth (request_rec *r) { ! return run_method (r, offsets_into_method_ptrs.auth_checker, 0); } int invoke_handler (request_rec *r) *************** *** 391,396 **** --- 472,479 ---- if (m->module_index == -1) { m->module_index = num_modules++; } + /** XXX: this will be slow if there's lots of add_modules */ + build_method_shortcuts (); } void setup_prelinked_modules ()