diff --git a/auto/unix b/auto/unix
index 10835f6c..512681db 100644
|
a
|
b
|
if [ $ngx_found = no ]; then
|
| 299 | 299 | fi |
| 300 | 300 | fi |
| 301 | 301 | |
| | 302 | ngx_feature="clock_gettime(CLOCK_MONOTONIC)" |
| | 303 | ngx_feature_name="NGX_HAVE_CLOCK_MONOTONIC" |
| | 304 | ngx_feature_run=no |
| | 305 | ngx_feature_incs="#include <time.h>" |
| | 306 | ngx_feature_path= |
| | 307 | ngx_feature_libs= |
| | 308 | ngx_feature_test="struct timespec monotime; clock_gettime(CLOCK_MONOTONIC, &monotime);" |
| | 309 | . auto/feature |
| | 310 | |
| | 311 | |
| | 312 | if [ $ngx_found != yes ]; then |
| | 313 | |
| | 314 | ngx_feature="clock_gettime(CLOCK_MONOTONIC) in librt" |
| | 315 | ngx_feature_libs="-lrt" |
| | 316 | . auto/feature |
| | 317 | |
| | 318 | if [ $ngx_found = yes ]; then |
| | 319 | CORE_LIBS="$CORE_LIBS -lrt" |
| | 320 | fi |
| | 321 | fi |
| | 322 | |
| | 323 | if [ $ngx_found = yes ]; then |
| | 324 | # We have clock_gettime with CLOCK_MONOTONIC. Now we test for faster |
| | 325 | # variants (CLOCK_MONOTONIC_(FAST|COARSE)). ngx_feature_libs is set |
| | 326 | # by previous tests to include librt if necessary. |
| | 327 | ngx_feature="clock_gettime(CLOCK_MONOTONIC_FAST)" |
| | 328 | ngx_feature_name="NGX_HAVE_CLOCK_MONOTONIC_FAST" |
| | 329 | ngx_feature_test="struct timespec monotime; clock_gettime(CLOCK_MONOTONIC_FAST, &monotime);" |
| | 330 | . auto/feature |
| | 331 | |
| | 332 | ngx_feature="clock_gettime(CLOCK_MONOTONIC_COARSE)" |
| | 333 | ngx_feature_name="NGX_HAVE_CLOCK_MONOTONIC_COARSE" |
| | 334 | ngx_feature_test="struct timespec monotime; clock_gettime(CLOCK_MONOTONIC_COARSE, &monotime);" |
| | 335 | . auto/feature |
| | 336 | fi |
| 302 | 337 | |
| 303 | 338 | ngx_feature="sched_setaffinity()" |
| 304 | 339 | ngx_feature_name="NGX_HAVE_SCHED_SETAFFINITY" |
diff --git a/contrib/vim/syntax/nginx.vim b/contrib/vim/syntax/nginx.vim
index dc8c0cb4..4e87ba53 100644
|
a
|
b
|
syn keyword ngxDirective contained merge_slashes
|
| 334 | 334 | syn keyword ngxDirective contained min_delete_depth |
| 335 | 335 | syn keyword ngxDirective contained modern_browser |
| 336 | 336 | syn keyword ngxDirective contained modern_browser_value |
| | 337 | syn keyword ngxDirective contained monotonic_timers |
| 337 | 338 | syn keyword ngxDirective contained mp4 |
| 338 | 339 | syn keyword ngxDirective contained mp4_buffer_size |
| 339 | 340 | syn keyword ngxDirective contained mp4_max_buffer_size |
diff --git a/src/core/nginx.c b/src/core/nginx.c
index c3a29cc4..40108636 100644
|
a
|
b
|
static ngx_command_t ngx_core_commands[] = {
|
| 152 | 152 | 0, |
| 153 | 153 | NULL }, |
| 154 | 154 | |
| | 155 | #if (NGX_HAVE_CLOCK_MONOTONIC) |
| | 156 | { ngx_string("monotonic_timers"), |
| | 157 | NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG, |
| | 158 | ngx_conf_set_flag_slot, |
| | 159 | 0, |
| | 160 | offsetof(ngx_core_conf_t, monotonic_timers), |
| | 161 | NULL }, |
| | 162 | #endif |
| | 163 | |
| 155 | 164 | ngx_null_command |
| 156 | 165 | }; |
| 157 | 166 | |
| … |
… |
ngx_core_module_create_conf(ngx_cycle_t *cycle)
|
| 1028 | 1037 | ccf->master = NGX_CONF_UNSET; |
| 1029 | 1038 | ccf->timer_resolution = NGX_CONF_UNSET_MSEC; |
| 1030 | 1039 | ccf->shutdown_timeout = NGX_CONF_UNSET_MSEC; |
| | 1040 | ccf->monotonic_timers = NGX_CONF_UNSET; |
| 1031 | 1041 | |
| 1032 | 1042 | ccf->worker_processes = NGX_CONF_UNSET; |
| 1033 | 1043 | ccf->debug_points = NGX_CONF_UNSET; |
| … |
… |
ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
|
| 1057 | 1067 | ngx_conf_init_value(ccf->master, 1); |
| 1058 | 1068 | ngx_conf_init_msec_value(ccf->timer_resolution, 0); |
| 1059 | 1069 | ngx_conf_init_msec_value(ccf->shutdown_timeout, 0); |
| | 1070 | ngx_conf_init_value(ccf->monotonic_timers, 0); |
| 1060 | 1071 | |
| 1061 | 1072 | ngx_conf_init_value(ccf->worker_processes, 1); |
| 1062 | 1073 | ngx_conf_init_value(ccf->debug_points, 0); |
diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h
index 2b48ccbd..f6cba531 100644
|
a
|
b
|
typedef struct {
|
| 114 | 114 | |
| 115 | 115 | ngx_array_t env; |
| 116 | 116 | char **environment; |
| | 117 | |
| | 118 | ngx_flag_t monotonic_timers; |
| 117 | 119 | } ngx_core_conf_t; |
| 118 | 120 | |
| 119 | 121 | |
diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c
index b2edf1a5..c0fe01aa 100644
|
a
|
b
|
static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
| 59 | 59 | static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", |
| 60 | 60 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; |
| 61 | 61 | |
| | 62 | #if (NGX_HAVE_CLOCK_MONOTONIC) |
| | 63 | static ngx_flag_t enable_monotonic = 0; |
| | 64 | static clockid_t monotonic_clock; |
| | 65 | #endif |
| | 66 | |
| 62 | 67 | void |
| 63 | 68 | ngx_time_init(void) |
| 64 | 69 | { |
| … |
… |
ngx_time_init(void)
|
| 73 | 78 | ngx_time_update(); |
| 74 | 79 | } |
| 75 | 80 | |
| | 81 | void |
| | 82 | ngx_time_enable_monotonic(ngx_flag_t enable) |
| | 83 | { |
| | 84 | #if (NGX_HAVE_CLOCK_MONOTONIC) |
| | 85 | struct timespec monotime; |
| | 86 | |
| | 87 | if (enable) { |
| | 88 | /* Hack for the 'else if's to work correctly with the '#if's */ |
| | 89 | if (0) { |
| | 90 | } |
| | 91 | #if (NGX_HAVE_CLOCK_MONOTONIC_FAST) |
| | 92 | else if (clock_gettime(CLOCK_MONOTONIC_FAST, &monotime) == 0) { |
| | 93 | monotonic_clock = CLOCK_MONOTONIC_FAST; |
| | 94 | } |
| | 95 | #endif |
| | 96 | #if (NGX_HAVE_CLOCK_MONOTONIC_COARSE) |
| | 97 | else if (clock_gettime(CLOCK_MONOTONIC_COARSE, &monotime) == 0) { |
| | 98 | monotonic_clock = CLOCK_MONOTONIC_COARSE; |
| | 99 | } |
| | 100 | #endif |
| | 101 | else if (clock_gettime(CLOCK_MONOTONIC, &monotime) == 0) { |
| | 102 | monotonic_clock = CLOCK_MONOTONIC; |
| | 103 | } else { |
| | 104 | /* No monotonic clock found at runtime, must disable. FIXME should this emit a warning? */ |
| | 105 | enable = 0; |
| | 106 | } |
| | 107 | } |
| | 108 | enable_monotonic = enable; |
| | 109 | ngx_time_update(); |
| | 110 | #endif |
| | 111 | } |
| 76 | 112 | |
| 77 | 113 | void |
| 78 | 114 | ngx_time_update(void) |
| … |
… |
ngx_time_update(void)
|
| 93 | 129 | sec = tv.tv_sec; |
| 94 | 130 | msec = tv.tv_usec / 1000; |
| 95 | 131 | |
| 96 | | ngx_current_msec = (ngx_msec_t) sec * 1000 + msec; |
| | 132 | #if (NGX_HAVE_CLOCK_MONOTONIC) |
| | 133 | if (enable_monotonic) { |
| | 134 | struct timespec monotime; |
| | 135 | clock_gettime(monotonic_clock, &monotime); |
| | 136 | ngx_current_msec = (ngx_msec_t) (monotime.tv_sec) * 1000 + (monotime.tv_nsec / 1000 / 1000); |
| | 137 | } else { |
| | 138 | #endif |
| | 139 | ngx_current_msec = (ngx_msec_t) sec * 1000 + msec; |
| | 140 | #if (NGX_HAVE_CLOCK_MONOTONIC) |
| | 141 | } |
| | 142 | #endif |
| | 143 | |
| 97 | 144 | |
| 98 | 145 | tp = &cached_time[slot]; |
| 99 | 146 | |
diff --git a/src/core/ngx_times.h b/src/core/ngx_times.h
index 94aedcdc..b9ffd9eb 100644
|
a
|
b
|
typedef struct {
|
| 21 | 21 | |
| 22 | 22 | |
| 23 | 23 | void ngx_time_init(void); |
| | 24 | void ngx_time_enable_monotonic(ngx_flag_t enable); |
| 24 | 25 | void ngx_time_update(void); |
| 25 | 26 | void ngx_time_sigsafe_update(void); |
| 26 | 27 | u_char *ngx_http_time(u_char *buf, time_t t); |
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 57af8132..5d9d6701 100644
|
a
|
b
|
ngx_event_process_init(ngx_cycle_t *cycle)
|
| 601 | 601 | ngx_queue_init(&ngx_posted_accept_events); |
| 602 | 602 | ngx_queue_init(&ngx_posted_events); |
| 603 | 603 | |
| | 604 | /* |
| | 605 | * Monotonic time must be enabled before the first timer is created. Otherwise |
| | 606 | * monotonic and realtime timestamps would be mixed in the rbtree. |
| | 607 | */ |
| | 608 | ngx_time_enable_monotonic(ccf->monotonic_timers); |
| 604 | 609 | if (ngx_event_timer_init(cycle->log) == NGX_ERROR) { |
| 605 | 610 | return NGX_ERROR; |
| 606 | 611 | } |