X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=helper_thread.c;h=a2fb7c29a0565884e96e9546a6967ee2de889181;hb=e235e74dfd0627b17690194f957da509b8ace808;hp=28f6cca323d303fc370877610ba65513d509cd39;hpb=52a552e21ae25eb175f686935fe85a2956f949ce;p=fio.git diff --git a/helper_thread.c b/helper_thread.c index 28f6cca3..a2fb7c29 100644 --- a/helper_thread.c +++ b/helper_thread.c @@ -1,3 +1,4 @@ +#include #ifdef CONFIG_VALGRIND_DEV #include #else @@ -127,16 +128,47 @@ void helper_thread_exit(void) pthread_join(helper_data->thread, NULL); } +static unsigned int task_helper(struct timespec *last, struct timespec *now, unsigned int period, void do_task()) +{ + unsigned int next, since; + + since = mtime_since(last, now); + if (since >= period || period - since < 10) { + do_task(); + timespec_add_msec(last, since); + if (since > period) + next = period - (since - period); + else + next = period; + } else + next = period - since; + + return next; +} + static void *helper_thread_main(void *data) { struct helper_data *hd = data; - unsigned int msec_to_next_event, next_log, next_ss = STEADYSTATE_MSEC; - struct timespec ts, last_du, last_ss; + unsigned int msec_to_next_event, next_log, next_si = status_interval; + unsigned int next_ss = STEADYSTATE_MSEC; + struct timespec ts, last_du, last_ss, last_si; char action; int ret = 0; sk_out_assign(hd->sk_out); +#ifdef HAVE_PTHREAD_SIGMASK + { + sigset_t sigmask; + + /* Let another thread handle signals. */ + ret = pthread_sigmask(SIG_UNBLOCK, NULL, &sigmask); + assert(ret == 0); + ret = pthread_sigmask(SIG_BLOCK, &sigmask, NULL); + assert(ret == 0); + } +#endif + #ifdef CONFIG_PTHREAD_CONDATTR_SETCLOCK clock_gettime(CLOCK_MONOTONIC, &ts); #else @@ -144,26 +176,29 @@ static void *helper_thread_main(void *data) #endif memcpy(&last_du, &ts, sizeof(ts)); memcpy(&last_ss, &ts, sizeof(ts)); + memcpy(&last_si, &ts, sizeof(ts)); fio_sem_up(hd->startup_sem); msec_to_next_event = DISK_UTIL_MSEC; while (!ret && !hd->exit) { - uint64_t since_du, since_ss = 0; + uint64_t since_du; struct timeval timeout = { - .tv_sec = DISK_UTIL_MSEC / 1000, - .tv_usec = (DISK_UTIL_MSEC % 1000) * 1000, + .tv_sec = msec_to_next_event / 1000, + .tv_usec = (msec_to_next_event % 1000) * 1000, }; fd_set rfds, efds; - timespec_add_msec(&ts, msec_to_next_event); - if (read_from_pipe(hd->pipe[0], &action, sizeof(action)) < 0) { FD_ZERO(&rfds); FD_SET(hd->pipe[0], &rfds); FD_ZERO(&efds); FD_SET(hd->pipe[0], &efds); - select(1, &rfds, NULL, &efds, &timeout); + if (select(1, &rfds, NULL, &efds, &timeout) < 0) { + log_err("fio: select() call in helper thread failed: %s", + strerror(errno)); + ret = 1; + } if (read_from_pipe(hd->pipe[0], &action, sizeof(action)) < 0) action = 0; @@ -193,25 +228,23 @@ static void *helper_thread_main(void *data) if (action == A_DO_STAT) __show_running_run_stats(); + if (status_interval) { + next_si = task_helper(&last_si, &ts, status_interval, __show_running_run_stats); + msec_to_next_event = min(next_si, msec_to_next_event); + } + next_log = calc_log_samples(); if (!next_log) next_log = DISK_UTIL_MSEC; if (steadystate_enabled) { - since_ss = mtime_since(&last_ss, &ts); - if (since_ss >= STEADYSTATE_MSEC || STEADYSTATE_MSEC - since_ss < 10) { - steadystate_check(); - timespec_add_msec(&last_ss, since_ss); - if (since_ss > STEADYSTATE_MSEC) - next_ss = STEADYSTATE_MSEC - (since_ss - STEADYSTATE_MSEC); - else - next_ss = STEADYSTATE_MSEC; - } else - next_ss = STEADYSTATE_MSEC - since_ss; + next_ss = task_helper(&last_ss, &ts, STEADYSTATE_MSEC, steadystate_check); + msec_to_next_event = min(next_ss, msec_to_next_event); } - msec_to_next_event = min(min(next_log, msec_to_next_event), next_ss); - dprint(FD_HELPERTHREAD, "since_ss: %llu, next_ss: %u, next_log: %u, msec_to_next_event: %u\n", (unsigned long long)since_ss, next_ss, next_log, msec_to_next_event); + msec_to_next_event = min(next_log, msec_to_next_event); + dprint(FD_HELPERTHREAD, "next_si: %u, next_ss: %u, next_log: %u, msec_to_next_event: %u\n", + next_si, next_ss, next_log, msec_to_next_event); if (!is_backend) print_thread_status();