From ed6cb5e8459a7ad319d6127a4d4179800879dd4d Mon Sep 17 00:00:00 2001 From: Kirill A. Korinskiy Date: Thu, 5 Mar 2009 22:44:06 +0300 Subject: [PATCH] Implement `ngx_clock_gettime' and optional chip `ngx_gettimeofday' Cc: catap@catap.ru `ngx_gettimeofday' very expensive operation and I replace it to simple function around of `ngx_clock_gettime(NGX_CLOCK_PROFILE)'. In first call this function calculated `timeval' of start worker and for next call add to starting `timeval' value time of life this worker gtetting by `ngx_clock_gettime(NGX_CLOCK_PROFILE)'. for switch on `ngx_gettimeofday' use `--with-clock_gettimeofday' as ./configure options Signed-off-by: Kirill A. Korinskiy --- auto/lib/conf | 4 + auto/options | 9 +++ src/core/ngx_times.c | 2 +- src/event/modules/ngx_select_module.c | 2 +- src/http/modules/ngx_http_userid_filter_module.c | 2 +- src/os/unix/ngx_time.c | 65 ++++++++++++++++++++++ src/os/unix/ngx_time.h | 51 +++++++++++++++++ 7 files changed, 132 insertions(+), 3 deletions(-) diff --git a/auto/lib/conf b/auto/lib/conf index 0462228ab7e580d5ee5eb2ed5650af46c81f062c..487d4376bfe21682b533e0aea03872945dac79e9 100644 --- a/auto/lib/conf +++ b/auto/lib/conf @@ -52,3 +52,7 @@ fi if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then . auto/lib/google-perftools/conf fi + +if [ $NGX_CLOCK = YES ]; then + . auto/lib/clock/conf +fi diff --git a/auto/options b/auto/options index fabd5d0d15668f321b84e5b00c7c395f19b761ab..69e379363d6fd4685334c8352a76716f02880198 100644 --- a/auto/options +++ b/auto/options @@ -126,6 +126,9 @@ USE_LIBXSLT=NO NGX_GOOGLE_PERFTOOLS=NO NGX_CPP_TEST=NO +NGX_CLOCK=YES +NGX_CLOCK_GETTIMEOFDAY=NO + NGX_CPU_CACHE_LINE= @@ -221,6 +224,9 @@ do --with-google_perftools_module) NGX_GOOGLE_PERFTOOLS=YES ;; --with-cpp_test_module) NGX_CPP_TEST=YES ;; + --without-clock) NGX_CLOCK=NO ;; + --with-clock_gettimeofday) NGX_CLOCK_GETTIMEOFDAY=YES ;; + --add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;; --with-cc=*) CC="$value" ;; @@ -346,6 +352,9 @@ cat << END --with-google_perftools_module enable ngx_google_perftools_module --with-cpp_test_module enable ngx_cpp_test_module + --without-clock disable clock_gettime usage + --with-clock_gettimeofday enable clock_gettimeofday usage if it possible + --add-module=PATH enable an external module --with-cc=PATH set path to C compiler diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c index 3105beb47f4b8cf8241adb7e67c6129b04c1d752..4f5d857d955bfa8089752dd824f11f2724e987ea 100644 --- a/src/core/ngx_times.c +++ b/src/core/ngx_times.c @@ -60,7 +60,7 @@ ngx_time_update(time_t sec, ngx_uint_t msec) u_char *p0, *p1, *p2; ngx_tm_t tm, gmt; ngx_time_t *tp; - struct timeval tv; + ngx_timeval_t tv; if (!ngx_trylock(&ngx_time_lock)) { return; diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c index a50088ba45296305c6921d5e400575141887dd61..55fbaa81436f34c0450485d725e16c5b7371d436 100644 --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -253,7 +253,7 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_err_t err; ngx_event_t *ev, **queue; ngx_connection_t *c; - struct timeval tv, *tp; + ngx_timeval_t tv, *tp; #if !(NGX_WIN32) diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c index 5ffb1d02b4de82d01477b7401faf023b69a517e3..270b70a61bc54c8c4f010b022d63b1adeb426ff1 100644 --- a/src/http/modules/ngx_http_userid_filter_module.c +++ b/src/http/modules/ngx_http_userid_filter_module.c @@ -770,7 +770,7 @@ ngx_http_userid_mark(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) static ngx_int_t ngx_http_userid_init_worker(ngx_cycle_t *cycle) { - struct timeval tp; + ngx_timeval_t tp; ngx_gettimeofday(&tp); diff --git a/src/os/unix/ngx_time.c b/src/os/unix/ngx_time.c index 4ca8be672494c204b2c91bf1d76169a46173d7c1..6493906ce694b33de35e82aeebb3a9e8de134104 100644 --- a/src/os/unix/ngx_time.c +++ b/src/os/unix/ngx_time.c @@ -101,3 +101,68 @@ ngx_libc_gmtime(time_t s, struct tm *tm) #endif } + +#if (NGX_CLOCK) +ngx_timespec_t +ngx_timespec_diff(ngx_timespec_t *start, ngx_timespec_t *end) +{ + ngx_timespec_t temp; + if ((end->tv_nsec - start->tv_nsec) < 0) { + temp.tv_sec = end->tv_sec - start->tv_sec-1; + temp.tv_nsec = 1000000000 + end->tv_nsec - start->tv_nsec; + } else { + temp.tv_sec = end->tv_sec - start->tv_sec; + temp.tv_nsec = end->tv_nsec - start->tv_nsec; + } + return temp; +} + +ngx_int_t +ngx_clock_gettime(ngx_clockid_t id, ngx_timespec_t *res) +{ + return (ngx_int_t)clock_gettime((clockid_t)id, (struct timespec*)res); +} + +#if (NGX_HAVE_CLOCK_PROFILE) +ngx_timeval_t ngx_gettimeofday_start_tv = {0, 0}; + +static void +ngx_gettimeofday_init() +{ + ngx_timespec_t ts; + ngx_timeval_t tv; + + gettimeofday(&tv, NULL); + ngx_clock_gettime(NGX_CLOCK_PROFILE, &ts); + + if ((tv.tv_usec - ts.tv_nsec/1000) < 0) { + ngx_gettimeofday_start_tv.tv_sec = tv.tv_sec - 1; + ngx_gettimeofday_start_tv.tv_usec = 1000000 + tv.tv_usec - ts.tv_nsec/1000; + } else { + ngx_gettimeofday_start_tv.tv_sec = tv.tv_sec; + ngx_gettimeofday_start_tv.tv_usec = tv.tv_usec - ts.tv_nsec/1000; + } +} + +void ngx_gettimeofday(ngx_timeval_t *tp) +{ + ngx_timespec_t ts; + + if (ngx_gettimeofday_start_tv.tv_sec == 0 && + ngx_gettimeofday_start_tv.tv_usec == 0) { + ngx_gettimeofday_init(); + } + + ngx_clock_gettime(NGX_CLOCK_PROFILE, &ts); + + if ((ts.tv_nsec/1000 + ngx_gettimeofday_start_tv.tv_usec) > 1000000) { + tp->tv_sec = ngx_gettimeofday_start_tv.tv_sec + 1; + tp->tv_sec = ngx_gettimeofday_start_tv.tv_usec + ts.tv_nsec/1000 - 1000000; + } else { + tp->tv_sec = ngx_gettimeofday_start_tv.tv_sec; + tp->tv_usec = ngx_gettimeofday_start_tv.tv_usec + ts.tv_nsec/1000; + } +} +#endif + +#endif diff --git a/src/os/unix/ngx_time.h b/src/os/unix/ngx_time.h index 5d9406cdebc55ade2f82aa1c22bb839c370b27af..6a74768e7a44e659a482d081656e94e8cbe8f4f5 100644 --- a/src/os/unix/ngx_time.h +++ b/src/os/unix/ngx_time.h @@ -16,6 +16,7 @@ typedef ngx_rbtree_key_t ngx_msec_t; typedef ngx_rbtree_key_int_t ngx_msec_int_t; typedef struct tm ngx_tm_t; +typedef struct timeval ngx_timeval_t; #define ngx_tm_sec tm_sec #define ngx_tm_min tm_min @@ -57,7 +58,57 @@ void ngx_localtime(time_t s, ngx_tm_t *tm); void ngx_libc_localtime(time_t s, struct tm *tm); void ngx_libc_gmtime(time_t s, struct tm *tm); + +#if (NGX_CLOCK) + +typedef struct timespec ngx_timespec_t; +typedef clockid_t ngx_clockid_t; + +#if (NGX_HAVE_CLOCK_REALTIME) +#define NGX_CLOCK_REALTIME CLOCK_REALTIME +#endif /* NGX_HAVE_CLOCK_REALTIME */ + +#if (NGX_HAVE_CLOCK_VIRTUAL) +#define NGX_CLOCK_VIRTUAL CLOCK_VIRTUAL +#endif /* NGX_HAVE_CLOCK_VIRTUAL */ + +#if (NGX_HAVE_CLOCK_MONOTONIC) +#define NGX_CLOCK_MONOTONIC CLOCK_MONOTONIC +#endif /* NGX_HAVE_CLOCK_MONOTONIC */ + +#if (NGX_HAVE_CLOCK_PROCESS_CPUTIME_ID) +#define NGX_CLOCK_PROCESS_CPUTIME_ID CLOCK_PROCESS_CPUTIME_ID +#endif /* NGX_HAVE_CLOCK_PROCESS_CPUTIME_ID */ + +#if (NGX_HAVE_CLOCK_THREAD_CPUTIME_ID) +#define NGX_CLOCK_THREAD_CPUTIME_ID CLOCK_THREAD_CPUTIME_ID +#endif /* NGX_HAVE_CLOCK_THREAD_CPUTIME_ID */ + +#if (NGX_HAVE_CLOCK_PROFILE) +#define NGX_CLOCK_PROFILE CLOCK_PROFILE +#endif /* NGX_HAVE_CLOCK_PROFILE */ + +#if (NGX_HAVE_CLOCK_PROF) +#define NGX_CLOCK_PROFILE CLOCK_PROF +#endif /* NGX_HAVE_CLOCK_PROF */ + +#if (NGX_HAVE_CLOCK_UPTIME) +#define NGX_CLOCK_UPTIME CLOCK_UPTIME +#endif /* NGX_HAVE_CLOCK_PROF */ + +ngx_timespec_t ngx_timespec_diff(ngx_timespec_t *start, ngx_timespec_t *end); +ngx_int_t ngx_clock_gettime(ngx_clockid_t id, ngx_timespec_t *res); + +#endif /* NGX_CLOCK */ + +#if (NGX_CLOCK) && (NGX_HAVE_CLOCK_PROFILE) +extern ngx_timespec_t ngx_gettimeofday_start_ts; + +void ngx_gettimeofday(ngx_timeval_t *tp); +#else #define ngx_gettimeofday(tp) (void) gettimeofday(tp, NULL); +#endif /* (NGX_CLOCK) && (NGX_HAVE_CLOCK_MONOTONIC) */ + #define ngx_msleep(ms) (void) usleep(ms * 1000) #define ngx_sleep(s) (void) sleep(s) -- 1.5.6.5