X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=helper_thread.c;fp=helper_thread.c;h=2d553654c0814d29bc76a4038d97d547e5558adc;hp=f6cdddb8f0532af5be1a0463bb7d9fadf694500f;hb=696378af1212312425975d739acb54277616f8c9;hpb=df9bd7d452dfdcebfc1bdf317c74c3af09cc9719 diff --git a/helper_thread.c b/helper_thread.c index f6cdddb8..2d553654 100644 --- a/helper_thread.c +++ b/helper_thread.c @@ -1,5 +1,8 @@ #include #include +#ifdef CONFIG_HAVE_TIMERFD_CREATE +#include +#endif #ifdef CONFIG_VALGRIND_DEV #include #else @@ -13,6 +16,7 @@ #include "pshared.h" static int sleep_accuracy_ms; +static int timerfd = -1; enum action { A_EXIT = 1, @@ -179,6 +183,7 @@ static uint8_t wait_for_action(int fd, unsigned int timeout_ms) }; fd_set rfds, efds; uint8_t action = 0; + uint64_t exp; int res; res = read_from_pipe(fd, &action, sizeof(action)); @@ -188,7 +193,25 @@ static uint8_t wait_for_action(int fd, unsigned int timeout_ms) FD_SET(fd, &rfds); FD_ZERO(&efds); FD_SET(fd, &efds); - res = select(fd + 1, &rfds, NULL, &efds, &timeout); +#ifdef CONFIG_HAVE_TIMERFD_CREATE + { + /* + * If the timer frequency is 100 Hz, select() will round up + * `timeout` to the next multiple of 1 / 100 Hz = 10 ms. Hence + * use a high-resolution timer if possible to increase + * select() timeout accuracy. + */ + struct itimerspec delta = {}; + + delta.it_value.tv_sec = timeout.tv_sec; + delta.it_value.tv_nsec = timeout.tv_usec * 1000; + res = timerfd_settime(timerfd, 0, &delta, NULL); + assert(res == 0); + FD_SET(timerfd, &rfds); + } +#endif + res = select(max(fd, timerfd) + 1, &rfds, NULL, &efds, + timerfd >= 0 ? NULL : &timeout); if (res < 0) { log_err("fio: select() call in helper thread failed: %s", strerror(errno)); @@ -196,6 +219,10 @@ static uint8_t wait_for_action(int fd, unsigned int timeout_ms) } if (FD_ISSET(fd, &rfds)) read_from_pipe(fd, &action, sizeof(action)); + if (timerfd >= 0 && FD_ISSET(timerfd, &rfds)) { + res = read(timerfd, &exp, sizeof(exp)); + assert(res == sizeof(exp)); + } return action; } @@ -272,6 +299,12 @@ static void *helper_thread_main(void *data) assert(clk_tck > 0); sleep_accuracy_ms = (1000 + clk_tck - 1) / clk_tck; +#ifdef CONFIG_HAVE_TIMERFD_CREATE + timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); + assert(timerfd >= 0); + sleep_accuracy_ms = 1; +#endif + sk_out_assign(hd->sk_out); /* Let another thread handle signals. */ @@ -317,6 +350,11 @@ static void *helper_thread_main(void *data) print_thread_status(); } + if (timerfd >= 0) { + close(timerfd); + timerfd = -1; + } + fio_writeout_logs(false); sk_out_drop();