Doesn't this remove the advantage of using apr_time_t's? The whole point
of that format was that we were using microseconds instead of seconds. If
that is our goal, then why don't we just change what an apr_time_t is?
Ryan
On Fri, 23 Feb 2001, Bill Stoddard wrote:
> The essence of this patch is:
>
> apr_now() calls st_time() rather than a native system call
>
> st_time() returns time with one second resolution, which means it probably
> caches the time and updates the cache once per second. If the server serves
> 1000 cps, this saves 999 calls to determine the system time per second.
>
> The rest of the changes leverage the reduced resolution which makes possible
> simpler conversion/formatting functions and caching (of the string to go into
> the Date: header for instance) available to other time functions.
>
> This patch would need to be reimplemented to not rely on the state thread
> library and would need to be made portable to all platforms and MPMs.
>
> FWIW, I did this exact same thing with the IBM AFPA cache on NT several years
> back to handle Date: timestamps. A timer thread pops once per second to
> update the cached Date: string (among other things). I kept two copies of the
> string, a 'live' string and an 'update' string and ping-ponged between the two
> each timer pop which made locking during updates unnecessary. It was good for
> a few % performance boost :-)
>
> Bill
>
>
> diff -Naur apache_2.0a6/10xpatchlevel-1 apache_2.0a6/10xpatchlevel
> --- apache_2.0a6/10xpatchlevel-1 Thu Sep 7 21:06:35 2000
> +++ apache_2.0a6/10xpatchlevel Thu Sep 7 22:03:36 2000
> @@ -2,4 +2,4 @@
> available from
> http://oss.sgi.com/projects/apache/
>
> -10xpatchlevel=2.0a6-1
> +10xpatchlevel=2.0a6-2
> diff -Naur apache_2.0a6/htdocs/manual/stm.html-1
> apache_2.0a6/htdocs/manual/stm.html
> --- apache_2.0a6/htdocs/manual/stm.html-1 Thu Sep 7 21:26:55 2000
> +++ apache_2.0a6/htdocs/manual/stm.html Thu Sep 7 22:03:57 2000
> @@ -368,6 +368,29 @@
>
> </TD>
> </TR>
> + <TR>
> + <TD WIDTH=25%>
> + <CODE>USE_ST_TIME</CODE>
> + </TD>
> + <TD>
> +
> + Enables more efficient but less accurate time-of-day
> + queries. Only the presence or absence of this token is
> + meaningful; the value is ignored.
> +
> + <P>Apache/2.0 queries the current time of day with
> + one-microsecond resolution upon receipt of each request.
> + One-second resolution usually suffices and is more efficient
> + to query under heavy load (because it uses the state
> + threads library's <A
> +
> HREF="http://oss.sgi.com/projects/state-threads/docs/reference.html#time">time
> + cache</A>). This option switches to one-second resolution.
> +
> + <P>Default: <CODE>USE_ST_TIME</CODE> is not defined so
> + timekeeping is not accelerated.
> +
> + </TD>
> + </TR>
> </TABLE>
>
> <H3><A NAME="directives">3.2. Configuration Directives</A></H3>
> diff -Naur apache_2.0a6/src/lib/apr/time/unix/time.c-1
> apache_2.0a6/src/lib/apr/time/unix/time.c
> --- apache_2.0a6/src/lib/apr/time/unix/time.c-1 Sat Aug 5 23:07:32 2000
> +++ apache_2.0a6/src/lib/apr/time/unix/time.c Thu Sep 7 22:04:50 2000
> @@ -73,6 +73,9 @@
> #ifdef BEOS
> #include <sys/socket.h> /* for select */
> #endif
> +#ifdef USE_ST_TIME
> +#include <st.h>
> +#endif
> /* End System Headers */
>
>
> @@ -85,9 +88,13 @@
>
> apr_time_t apr_now(void)
> {
> +#ifdef USE_ST_TIME
> + return st_time() * APR_USEC_PER_SEC;
> +#else
> struct timeval tv;
> gettimeofday(&tv, NULL);
> return tv.tv_sec * APR_USEC_PER_SEC + tv.tv_usec;
> +#endif
> }
>
>
> @@ -166,14 +173,23 @@
> #else
> /* need to create tm_gmtoff... assume we are never more than 24 hours
> away */
> {
> + static struct {
> + time_t time;
> + apr_int32_t gmtoff;
> + } last; /* See apr_rfc822_date() */
> int days, hours, minutes;
>
> - tmx = gmtime(&t);
> - days = result->tm_yday - tmx->tm_yday;
> - hours = ((days < -1 ? 24 : 1 < days ? -24 : days * 24)
> - + result->tm_hour - tmx->tm_hour);
> - minutes = hours * 60 + result->tm_min - tmx->tm_min;
> - result->tm_gmtoff = minutes * 60;
> + if (t == last.time)
> + result->tm_gmtoff = last.gmtoff;
> + else {
> + tmx = gmtime(&t);
> + days = result->tm_yday - tmx->tm_yday;
> + hours = ((days < -1 ? 24 : 1 < days ? -24 : days * 24)
> + + result->tm_hour - tmx->tm_hour);
> + minutes = hours * 60 + result->tm_min - tmx->tm_min;
> + last.time = t;
> + result->tm_gmtoff = last.gmtoff = minutes * 60;
> + }
> }
> #endif
> #endif
> diff -Naur apache_2.0a6/src/lib/apr/time/unix/timestr.c-1
> apache_2.0a6/src/lib/apr/time/unix/timestr.c
> --- apache_2.0a6/src/lib/apr/time/unix/timestr.c-1 Sat Aug 5 23:07:33 2000
> +++ apache_2.0a6/src/lib/apr/time/unix/timestr.c Thu Sep 7 22:05:00 2000
> @@ -83,6 +83,28 @@
> const char *s;
> int real_year;
>
> +#if !APR_HAS_THREADS
> + /*
> + * Assume we're called most often to convert the current time of
> + * day. Since that changes at most once a second and this
> + * formatting function ignores the microseconds part, cache the
> + * result to avoid unnecessary formatting under very heavy load.
> + * Don't bother doing this in threaded servers because mutex locking
> + * the cached data probably would hurt more than caching would help.
> + */
> + static struct {
> + apr_time_t time;
> + time_t secs;
> + char str[APR_RFC822_DATE_LEN];
> + } last;
> + time_t secs;
> +
> + if (t == last.time || (secs = t / APR_USEC_PER_SEC) == last.secs) {
> + memcpy(date_str, last.str, APR_RFC822_DATE_LEN);
> + return APR_SUCCESS;
> + }
> +#endif
> +
> apr_explode_gmt(&xt, t);
>
> /* example: "Sat, 08 Jan 2000 18:31:41 GMT" */
> @@ -122,6 +144,13 @@
> *date_str++ = 'M';
> *date_str++ = 'T';
> *date_str++ = 0;
> +
> +#if !APR_HAS_THREADS
> + last.time = t;
> + last.secs = secs;
> + memcpy(last.str, date_str - APR_RFC822_DATE_LEN, APR_RFC822_DATE_LEN);
> +#endif
> +
> return APR_SUCCESS;
> }
>
> diff -Naur apache_2.0a6/src/main/http_main.c-1
> apache_2.0a6/src/main/http_main.c
> --- apache_2.0a6/src/main/http_main.c-1 Thu Sep 7 21:30:53 2000
> +++ apache_2.0a6/src/main/http_main.c Thu Sep 7 22:05:08 2000
> @@ -182,6 +182,9 @@
> #ifdef STM_VP_LIMIT
> printf(" -D STM_VP_LIMIT=%ld\n", (long) STM_VP_LIMIT);
> #endif
> +#ifdef USE_ST_TIME
> + printf(" -D USE_ST_TIME\n");
> +#endif
>
> /* This list displays the compiled in default paths: */
> #ifdef HTTPD_ROOT
> diff -Naur apache_2.0a6/src/modules/experimental/mod_mmap_static.c-1
> apache_2.0a6/src/modules/experimental/mod_mmap_static.c
> --- apache_2.0a6/src/modules/experimental/mod_mmap_static.c-1 Sat Aug 5
> 23:07:38 2000
> +++ apache_2.0a6/src/modules/experimental/mod_mmap_static.c Thu Sep 7
> 22:05:28 2000
> @@ -128,6 +128,7 @@
> #include "http_request.h"
> #include "http_core.h"
> #include "apr_mmap.h"
> +#include "apr_strings.h"
>
> module MODULE_VAR_EXPORT mmap_static_module;
>
> @@ -135,6 +136,7 @@
> apr_mmap_t *mm;
> char *filename;
> apr_finfo_t finfo;
> + char mtimestr[APR_RFC822_DATE_LEN];
> } a_file;
>
> typedef struct {
> @@ -199,6 +201,7 @@
> }
> apr_close(fd);
> tmp.filename = apr_pstrdup(cmd->pool, filename);
> + apr_rfc822_date(tmp.mtimestr, tmp.finfo.mtime);
> sconf = ap_get_module_config(cmd->server->module_config,
> &mmap_static_module);
> new_file = apr_push_array(sconf->files);
> *new_file = tmp;
> @@ -297,7 +300,26 @@
> return errstatus;
>
> ap_update_mtime(r, match->finfo.mtime);
> - ap_set_last_modified(r);
> +
> + /*
> + * ap_set_last_modified() always converts the file mtime to a string
> + * which is slow. Accelerate the common case.
> + * ap_set_last_modified(r);
> + */
> + {
> + apr_time_t mod_time;
> + char *datestr;
> +
> + mod_time = ap_rationalize_mtime(r, r->mtime);
> + if (mod_time == match->finfo.mtime)
> + datestr = match->mtimestr;
> + else {
> + datestr = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
> + apr_rfc822_date(datestr, mod_time);
> + }
> + apr_table_setn(r->headers_out, "Last-Modified", datestr);
> + }
> +
> ap_set_etag(r);
> if (((errstatus = ap_meets_conditions(r)) != OK)
> || (errstatus = ap_set_content_length (r, match->finfo.size))) {
> diff -Naur apache_2.0a6/src/modules/standard/mod_log_config.c-1
> apache_2.0a6/src/modules/standard/mod_log_config.c
> --- apache_2.0a6/src/modules/standard/mod_log_config.c-1 Sat Aug 5 23:07:47
> 2000
> +++ apache_2.0a6/src/modules/standard/mod_log_config.c Thu Sep 7 22:06:11
> 2000
> @@ -386,9 +386,17 @@
>
> static const char *log_request_time(request_rec *r, char *a)
> {
> + apr_time_t t;
> apr_exploded_time_t xt;
> apr_size_t retcode;
> char tstr[MAX_STRING_LEN];
> +#if !APR_HAS_THREADS
> + /* Cache the last converted time. See apr_rfc822_date(). */
> + static struct {
> + apr_time_t time;
> + char str[32];
> + } last;
> +#endif
>
> /*
> hi. i think getting the time again at the end of the request
> @@ -402,17 +410,26 @@
> a problem with this, you can set the define. -djg
> */
> #ifdef I_INSIST_ON_EXTRA_CYCLES_FOR_CLF_COMPLIANCE
> - apr_explode_localtime(&xt, apr_now());
> + t = apr_now();
> #else
> - apr_explode_localtime(&xt, r->request_time);
> + t = r->request_time;
> #endif
> +
> if (a && *a) { /* Custom format */
> + apr_explode_localtime(&xt, t);
> apr_strftime(tstr, &retcode, MAX_STRING_LEN, a, &xt);
> + return apr_pstrdup(r->pool, tstr);
> }
> else { /* CLF format */
> char sign;
> int timz;
>
> +#if !APR_HAS_THREADS
> + if (t == last.time)
> + return last.str;
> +#endif
> +
> + apr_explode_localtime(&xt, t);
> timz = xt.tm_gmtoff;
> if (timz < 0) {
> timz = -timz;
> @@ -422,13 +439,24 @@
> sign = '+';
> }
>
> - apr_snprintf(tstr, sizeof(tstr), "[%02d/%s/%d:%02d:%02d:%02d
> %c%.2d%.2d]",
> + apr_snprintf(
> +#if APR_HAS_THREADS
> + tstr, sizeof(tstr),
> +#else
> + last.str, sizeof(last.str),
> +#endif
> + "[%02d/%s/%d:%02d:%02d:%02d %c%.2d%.2d]",
> xt.tm_mday, apr_month_snames[xt.tm_mon], xt.tm_year+1900,
> xt.tm_hour, xt.tm_min, xt.tm_sec,
> sign, timz / (60*60), timz % (60*60));
> - }
>
> - return apr_pstrdup(r->pool, tstr);
> +#if APR_HAS_THREADS
> + return apr_pstrdup(r->pool, tstr);
> +#else
> + last.time = t;
> + return last.str;
> +#endif
> + }
> }
>
> static const char *log_request_duration(request_rec *r, char *a)
>
>
>
>
_______________________________________________________________________________
Ryan Bloom [EMAIL PROTECTED]
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------