From: Timo Sirainen Date: Mon, 21 Sep 2015 10:59:41 +0000 (+0300) Subject: lib: Added io_loop_get_wait_usecs() X-Git-Tag: 2.2.19.rc1~34 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fb4bd85e7d254f65570d3c860b34fc3e963b25b6;p=thirdparty%2Fdovecot%2Fcore.git lib: Added io_loop_get_wait_usecs() --- diff --git a/src/lib/ioloop-private.h b/src/lib/ioloop-private.h index 9fbb18c252..b50f86179e 100644 --- a/src/lib/ioloop-private.h +++ b/src/lib/ioloop-private.h @@ -25,6 +25,7 @@ struct ioloop { io_loop_time_moved_callback_t *time_moved_callback; time_t next_max_time; + uint64_t ioloop_wait_usecs; unsigned int io_pending_count; diff --git a/src/lib/ioloop.c b/src/lib/ioloop.c index 87e452491a..1ee2673002 100644 --- a/src/lib/ioloop.c +++ b/src/lib/ioloop.c @@ -402,6 +402,12 @@ int io_loop_get_wait_time(struct ioloop *ioloop, struct timeval *tv_r) tv_now.tv_sec = 0; msecs = timeout_get_wait_time(timeout, tv_r, &tv_now); ioloop->next_max_time = (tv_now.tv_sec + msecs/1000) + 1; + + /* update ioloop_timeval - this is meant for io_loop_handle_timeouts()'s + ioloop_wait_usecs calculation. normally after this we go to the + ioloop and after that we update ioloop_timeval immediately again. */ + ioloop_timeval = tv_now; + ioloop_time = tv_now.tv_sec; return msecs; } @@ -466,7 +472,7 @@ static void io_loops_timeouts_update(long diff_secs) static void io_loop_handle_timeouts_real(struct ioloop *ioloop) { struct priorityq_item *item; - struct timeval tv, tv_call; + struct timeval tv, tv_call, prev_ioloop_timeval = ioloop_timeval; unsigned int t_id; if (gettimeofday(&ioloop_timeval, NULL) < 0) @@ -482,13 +488,17 @@ static void io_loop_handle_timeouts_real(struct ioloop *ioloop) /* the callback may have slept, so check the time again. */ if (gettimeofday(&ioloop_timeval, NULL) < 0) i_fatal("gettimeofday(): %m"); - } else if (unlikely(ioloop_timeval.tv_sec > - ioloop->next_max_time)) { - io_loops_timeouts_update(ioloop_timeval.tv_sec - - ioloop->next_max_time); - /* time moved forwards */ - ioloop->time_moved_callback(ioloop->next_max_time, - ioloop_timeval.tv_sec); + } else { + if (unlikely(ioloop_timeval.tv_sec > + ioloop->next_max_time)) { + io_loops_timeouts_update(ioloop_timeval.tv_sec - + ioloop->next_max_time); + /* time moved forwards */ + ioloop->time_moved_callback(ioloop->next_max_time, + ioloop_timeval.tv_sec); + } + ioloop->ioloop_wait_usecs += + timeval_diff_usecs(&ioloop_timeval, &prev_ioloop_timeval); } ioloop_time = ioloop_timeval.tv_sec; @@ -933,3 +943,8 @@ bool io_loop_have_immediate_timeouts(struct ioloop *ioloop) return io_loop_get_wait_time(ioloop, &tv) == 0; } + +uint64_t io_loop_get_wait_usecs(struct ioloop *ioloop) +{ + return ioloop->ioloop_wait_usecs; +} diff --git a/src/lib/ioloop.h b/src/lib/ioloop.h index 588ba54b1d..1ae8d5c399 100644 --- a/src/lib/ioloop.h +++ b/src/lib/ioloop.h @@ -185,5 +185,7 @@ bool io_loop_have_ios(struct ioloop *ioloop); /* Returns TRUE if there is a pending timeout that is going to be run immediately. */ bool io_loop_have_immediate_timeouts(struct ioloop *ioloop); +/* Returns number of microseconds spent on the ioloop waiting itself. */ +uint64_t io_loop_get_wait_usecs(struct ioloop *ioloop); #endif