From cd4aa053fce19660936cdeaa1a30340018665cc6 Mon Sep 17 00:00:00 2001 From: Toru Maesaka Date: Mon, 13 May 2019 16:04:33 -0700 Subject: [PATCH 1/6] socket: add an h2o_now_nanosec() function --- include/h2o/socket/evloop.h | 6 ++++++ include/h2o/socket/uv-binding.h | 5 +++++ lib/common/socket/evloop.c.h | 3 ++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/h2o/socket/evloop.h b/include/h2o/socket/evloop.h index 1afdd68d86..46e14a472b 100644 --- a/include/h2o/socket/evloop.h +++ b/include/h2o/socket/evloop.h @@ -43,6 +43,7 @@ typedef struct st_h2o_evloop_t { struct st_h2o_evloop_socket_t **tail_ref; } _statechanged; uint64_t _now; + uint64_t _now_ns; struct timeval _tv_at; h2o_timerwheel_t *_timeouts; h2o_sliding_counter_t exec_time_counter; @@ -82,6 +83,11 @@ static inline uint64_t h2o_now(h2o_evloop_t *loop) return loop->_now; } +static inline uint64_t h2o_now_nanosec(h2o_evloop_t *loop) +{ + return loop->_now_ns; +} + static inline uint64_t h2o_evloop_get_execution_time(h2o_evloop_t *loop) { return loop->exec_time_counter.average; diff --git a/include/h2o/socket/uv-binding.h b/include/h2o/socket/uv-binding.h index b08aedab22..00047006fc 100644 --- a/include/h2o/socket/uv-binding.h +++ b/include/h2o/socket/uv-binding.h @@ -62,6 +62,11 @@ static inline uint64_t h2o_now(h2o_loop_t *loop) return uv_now(loop); } +static inline uint64_t h2o_now_nanosec(h2o_evloop_t *loop) +{ + return uv_hrtime(); +} + inline void h2o_timer_init(h2o_timer_t *timer, h2o_timer_cb cb) { memset(timer, 0, sizeof(*timer)); diff --git a/lib/common/socket/evloop.c.h b/lib/common/socket/evloop.c.h index 624813a156..d2500d2d02 100644 --- a/lib/common/socket/evloop.c.h +++ b/lib/common/socket/evloop.c.h @@ -475,7 +475,8 @@ h2o_evloop_t *create_evloop(size_t sz) void update_now(h2o_evloop_t *loop) { gettimeofday(&loop->_tv_at, NULL); - loop->_now = (uint64_t)loop->_tv_at.tv_sec * 1000 + loop->_tv_at.tv_usec / 1000; + loop->_now_ns = (uint64_t)(loop->_tv_at.tv_sec * 1000000 + loop->_tv_at.tv_usec) * 1000; + loop->_now = loop->_now_ns / 1000000; } int32_t adjust_max_wait(h2o_evloop_t *loop, int32_t max_wait) From 6266069d37dc5b138af86d8834bfdd04c750ded6 Mon Sep 17 00:00:00 2001 From: Toru Maesaka Date: Mon, 13 May 2019 16:21:20 -0700 Subject: [PATCH 2/6] socket: rename evloop's `now` var to `now_ms` For clarity. Especially now that we have a now_ns variable. --- include/h2o/socket/evloop.h | 6 +++--- lib/common/socket/evloop.c.h | 12 ++++++------ lib/common/socket/evloop/kqueue.c.h | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/h2o/socket/evloop.h b/include/h2o/socket/evloop.h index 46e14a472b..6002220e83 100644 --- a/include/h2o/socket/evloop.h +++ b/include/h2o/socket/evloop.h @@ -42,7 +42,7 @@ typedef struct st_h2o_evloop_t { struct st_h2o_evloop_socket_t *head; struct st_h2o_evloop_socket_t **tail_ref; } _statechanged; - uint64_t _now; + uint64_t _now_ms; uint64_t _now_ns; struct timeval _tv_at; h2o_timerwheel_t *_timeouts; @@ -80,7 +80,7 @@ static inline struct timeval h2o_gettimeofday(h2o_evloop_t *loop) static inline uint64_t h2o_now(h2o_evloop_t *loop) { - return loop->_now; + return loop->_now_ms; } static inline uint64_t h2o_now_nanosec(h2o_evloop_t *loop) @@ -95,7 +95,7 @@ static inline uint64_t h2o_evloop_get_execution_time(h2o_evloop_t *loop) inline void h2o_timer_link(h2o_evloop_t *loop, uint64_t delay_ticks, h2o_timer_t *timer) { - h2o_timerwheel_link_abs(loop->_timeouts, timer, loop->_now + delay_ticks); + h2o_timerwheel_link_abs(loop->_timeouts, timer, loop->_now_ms + delay_ticks); } #endif diff --git a/lib/common/socket/evloop.c.h b/lib/common/socket/evloop.c.h index d2500d2d02..f53c19fb32 100644 --- a/lib/common/socket/evloop.c.h +++ b/lib/common/socket/evloop.c.h @@ -467,7 +467,7 @@ h2o_evloop_t *create_evloop(size_t sz) loop->_statechanged.tail_ref = &loop->_statechanged.head; update_now(loop); /* 3 levels * 32-slots => 1 second goes into 2nd, becomes O(N) above approx. 31 seconds */ - loop->_timeouts = h2o_timerwheel_create(3, loop->_now); + loop->_timeouts = h2o_timerwheel_create(3, loop->_now_ms); return loop; } @@ -476,7 +476,7 @@ void update_now(h2o_evloop_t *loop) { gettimeofday(&loop->_tv_at, NULL); loop->_now_ns = (uint64_t)(loop->_tv_at.tv_sec * 1000000 + loop->_tv_at.tv_usec) * 1000; - loop->_now = loop->_now_ns / 1000000; + loop->_now_ms = loop->_now_ns / 1000000; } int32_t adjust_max_wait(h2o_evloop_t *loop, int32_t max_wait) @@ -485,10 +485,10 @@ int32_t adjust_max_wait(h2o_evloop_t *loop, int32_t max_wait) update_now(loop); - if (wake_at <= loop->_now) { + if (wake_at <= loop->_now_ms) { max_wait = 0; } else { - uint64_t delta = wake_at - loop->_now; + uint64_t delta = wake_at - loop->_now_ms; if (delta < max_wait) max_wait = (int32_t)delta; } @@ -607,7 +607,7 @@ int h2o_evloop_run(h2o_evloop_t *loop, int32_t max_wait) while (1) { h2o_linklist_t expired; h2o_linklist_init_anchor(&expired); - h2o_timerwheel_get_expired(loop->_timeouts, loop->_now, &expired); + h2o_timerwheel_get_expired(loop->_timeouts, loop->_now_ms, &expired); if (h2o_linklist_is_empty(&expired)) break; do { @@ -623,7 +623,7 @@ int h2o_evloop_run(h2o_evloop_t *loop, int32_t max_wait) if (h2o_sliding_counter_is_running(&loop->exec_time_counter)) { update_now(loop); - h2o_sliding_counter_stop(&loop->exec_time_counter, loop->_now); + h2o_sliding_counter_stop(&loop->exec_time_counter, loop->_now_ms); } return 0; diff --git a/lib/common/socket/evloop/kqueue.c.h b/lib/common/socket/evloop/kqueue.c.h index 626ed936de..96aa605549 100644 --- a/lib/common/socket/evloop/kqueue.c.h +++ b/lib/common/socket/evloop/kqueue.c.h @@ -124,7 +124,7 @@ int evloop_do_proceed(h2o_evloop_t *_loop, int32_t max_wait) return -1; if (nevents != 0) - h2o_sliding_counter_start(&loop->super.exec_time_counter, loop->super._now); + h2o_sliding_counter_start(&loop->super.exec_time_counter, loop->super._now_ms); /* update readable flags, perform writes */ for (i = 0; i != nevents; ++i) { From ecb3d8ecf26088848c4743898ffa2b232823caf8 Mon Sep 17 00:00:00 2001 From: Toru Maesaka Date: Mon, 13 May 2019 17:47:52 -0700 Subject: [PATCH 3/6] socket: expand the ms/ns abbreviations --- include/h2o/socket/evloop.h | 10 +++++----- lib/common/socket/evloop.c.h | 14 +++++++------- lib/common/socket/evloop/kqueue.c.h | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/h2o/socket/evloop.h b/include/h2o/socket/evloop.h index 6002220e83..26ea9bd23e 100644 --- a/include/h2o/socket/evloop.h +++ b/include/h2o/socket/evloop.h @@ -42,8 +42,8 @@ typedef struct st_h2o_evloop_t { struct st_h2o_evloop_socket_t *head; struct st_h2o_evloop_socket_t **tail_ref; } _statechanged; - uint64_t _now_ms; - uint64_t _now_ns; + uint64_t _now_millisec; + uint64_t _now_nanosec; struct timeval _tv_at; h2o_timerwheel_t *_timeouts; h2o_sliding_counter_t exec_time_counter; @@ -80,12 +80,12 @@ static inline struct timeval h2o_gettimeofday(h2o_evloop_t *loop) static inline uint64_t h2o_now(h2o_evloop_t *loop) { - return loop->_now_ms; + return loop->_now_millisec; } static inline uint64_t h2o_now_nanosec(h2o_evloop_t *loop) { - return loop->_now_ns; + return loop->_now_nanosec; } static inline uint64_t h2o_evloop_get_execution_time(h2o_evloop_t *loop) @@ -95,7 +95,7 @@ static inline uint64_t h2o_evloop_get_execution_time(h2o_evloop_t *loop) inline void h2o_timer_link(h2o_evloop_t *loop, uint64_t delay_ticks, h2o_timer_t *timer) { - h2o_timerwheel_link_abs(loop->_timeouts, timer, loop->_now_ms + delay_ticks); + h2o_timerwheel_link_abs(loop->_timeouts, timer, loop->_now_millisec + delay_ticks); } #endif diff --git a/lib/common/socket/evloop.c.h b/lib/common/socket/evloop.c.h index f53c19fb32..3f28b75e79 100644 --- a/lib/common/socket/evloop.c.h +++ b/lib/common/socket/evloop.c.h @@ -467,7 +467,7 @@ h2o_evloop_t *create_evloop(size_t sz) loop->_statechanged.tail_ref = &loop->_statechanged.head; update_now(loop); /* 3 levels * 32-slots => 1 second goes into 2nd, becomes O(N) above approx. 31 seconds */ - loop->_timeouts = h2o_timerwheel_create(3, loop->_now_ms); + loop->_timeouts = h2o_timerwheel_create(3, loop->_now_millisec); return loop; } @@ -475,8 +475,8 @@ h2o_evloop_t *create_evloop(size_t sz) void update_now(h2o_evloop_t *loop) { gettimeofday(&loop->_tv_at, NULL); - loop->_now_ns = (uint64_t)(loop->_tv_at.tv_sec * 1000000 + loop->_tv_at.tv_usec) * 1000; - loop->_now_ms = loop->_now_ns / 1000000; + loop->_now_nanosec = (uint64_t)(loop->_tv_at.tv_sec * 1000000 + loop->_tv_at.tv_usec) * 1000; + loop->_now_millisec = loop->_now_nanosec / 1000000; } int32_t adjust_max_wait(h2o_evloop_t *loop, int32_t max_wait) @@ -485,10 +485,10 @@ int32_t adjust_max_wait(h2o_evloop_t *loop, int32_t max_wait) update_now(loop); - if (wake_at <= loop->_now_ms) { + if (wake_at <= loop->_now_millisec) { max_wait = 0; } else { - uint64_t delta = wake_at - loop->_now_ms; + uint64_t delta = wake_at - loop->_now_millisec; if (delta < max_wait) max_wait = (int32_t)delta; } @@ -607,7 +607,7 @@ int h2o_evloop_run(h2o_evloop_t *loop, int32_t max_wait) while (1) { h2o_linklist_t expired; h2o_linklist_init_anchor(&expired); - h2o_timerwheel_get_expired(loop->_timeouts, loop->_now_ms, &expired); + h2o_timerwheel_get_expired(loop->_timeouts, loop->_now_millisec, &expired); if (h2o_linklist_is_empty(&expired)) break; do { @@ -623,7 +623,7 @@ int h2o_evloop_run(h2o_evloop_t *loop, int32_t max_wait) if (h2o_sliding_counter_is_running(&loop->exec_time_counter)) { update_now(loop); - h2o_sliding_counter_stop(&loop->exec_time_counter, loop->_now_ms); + h2o_sliding_counter_stop(&loop->exec_time_counter, loop->_now_millisec); } return 0; diff --git a/lib/common/socket/evloop/kqueue.c.h b/lib/common/socket/evloop/kqueue.c.h index 96aa605549..dc28ed0882 100644 --- a/lib/common/socket/evloop/kqueue.c.h +++ b/lib/common/socket/evloop/kqueue.c.h @@ -124,7 +124,7 @@ int evloop_do_proceed(h2o_evloop_t *_loop, int32_t max_wait) return -1; if (nevents != 0) - h2o_sliding_counter_start(&loop->super.exec_time_counter, loop->super._now_ms); + h2o_sliding_counter_start(&loop->super.exec_time_counter, loop->super._now_millisec); /* update readable flags, perform writes */ for (i = 0; i != nevents; ++i) { From 5d0859142dc282864c2bf03cd9aae742f27f4e00 Mon Sep 17 00:00:00 2001 From: Toru Maesaka Date: Mon, 13 May 2019 19:58:45 -0700 Subject: [PATCH 4/6] socket: sadly uv_hrtime isn't based on the unix epoch --- include/h2o/socket/uv-binding.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/h2o/socket/uv-binding.h b/include/h2o/socket/uv-binding.h index 00047006fc..8d2979af23 100644 --- a/include/h2o/socket/uv-binding.h +++ b/include/h2o/socket/uv-binding.h @@ -62,9 +62,9 @@ static inline uint64_t h2o_now(h2o_loop_t *loop) return uv_now(loop); } -static inline uint64_t h2o_now_nanosec(h2o_evloop_t *loop) +static inline uint64_t h2o_now_nanosec(h2o_loop_t *loop) { - return uv_hrtime(); + return uv_now(loop) * 1000000; } inline void h2o_timer_init(h2o_timer_t *timer, h2o_timer_cb cb) From 9b47bf55daaaad6a9f8853562efb90abbdea7b6f Mon Sep 17 00:00:00 2001 From: Toru Maesaka Date: Mon, 13 May 2019 20:11:47 -0700 Subject: [PATCH 5/6] socket: fix errors discovered by travis-ci --- lib/common/socket/evloop/epoll.c.h | 2 +- lib/common/socket/evloop/poll.c.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/common/socket/evloop/epoll.c.h b/lib/common/socket/evloop/epoll.c.h index dd6107d22d..e959368404 100644 --- a/lib/common/socket/evloop/epoll.c.h +++ b/lib/common/socket/evloop/epoll.c.h @@ -118,7 +118,7 @@ int evloop_do_proceed(h2o_evloop_t *_loop, int32_t max_wait) return -1; if (nevents != 0) - h2o_sliding_counter_start(&loop->super.exec_time_counter, loop->super._now); + h2o_sliding_counter_start(&loop->super.exec_time_counter, loop->super._now_millisec); /* update readable flags, perform writes */ for (i = 0; i != nevents; ++i) { diff --git a/lib/common/socket/evloop/poll.c.h b/lib/common/socket/evloop/poll.c.h index c46ab9241d..73e73bf47c 100644 --- a/lib/common/socket/evloop/poll.c.h +++ b/lib/common/socket/evloop/poll.c.h @@ -110,7 +110,7 @@ int evloop_do_proceed(h2o_evloop_t *_loop, int32_t max_wait) /* update readable flags, perform writes */ if (ret > 0) { size_t i; - h2o_sliding_counter_start(&loop->super.exec_time_counter, loop->super._now); + h2o_sliding_counter_start(&loop->super.exec_time_counter, loop->super._now_millisec); for (i = 0; i != pollfds.size; ++i) { /* set read_ready flag before calling the write cb, since app. code invoked by the latter may close the socket, clearing * the former flag */ From b9e2997ee0507e93c4d80204874b59a2a4d85ef8 Mon Sep 17 00:00:00 2001 From: Toru Maesaka Date: Mon, 13 May 2019 20:16:47 -0700 Subject: [PATCH 6/6] cast loop->_tv_at.tv_sec to uint64_t before multiplying --- lib/common/socket/evloop.c.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/socket/evloop.c.h b/lib/common/socket/evloop.c.h index 3f28b75e79..fc215d560d 100644 --- a/lib/common/socket/evloop.c.h +++ b/lib/common/socket/evloop.c.h @@ -475,7 +475,7 @@ h2o_evloop_t *create_evloop(size_t sz) void update_now(h2o_evloop_t *loop) { gettimeofday(&loop->_tv_at, NULL); - loop->_now_nanosec = (uint64_t)(loop->_tv_at.tv_sec * 1000000 + loop->_tv_at.tv_usec) * 1000; + loop->_now_nanosec = ((uint64_t)loop->_tv_at.tv_sec * 1000000 + loop->_tv_at.tv_usec) * 1000; loop->_now_millisec = loop->_now_nanosec / 1000000; }