X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=backend.c;h=a93c458a9393e609371642d94e5900518327015e;hp=dd7dc67ea6bdae550a41d11a8cb6d9c844dcaf33;hb=b295dc29b3abebe968950ce792f3087077223b78;hpb=9d93ea65fc145a97f8f404db4eb5be763a1fff5d diff --git a/backend.c b/backend.c index dd7dc67e..a93c458a 100644 --- a/backend.c +++ b/backend.c @@ -55,9 +55,10 @@ #include "err.h" #include "lib/tp.h" -static pthread_t disk_util_thread; -static pthread_cond_t du_cond; -static pthread_mutex_t du_lock; +static pthread_t helper_thread; +static pthread_mutex_t helper_lock; +pthread_cond_t helper_cond; +int helper_do_stat = 0; static struct fio_mutex *startup_mutex; static struct flist_head *cgroup_list; @@ -75,7 +76,7 @@ unsigned int stat_number = 0; int shm_id = 0; int temp_stall_ts; unsigned long done_secs = 0; -volatile int disk_util_exit = 0; +volatile int helper_exit = 0; #define PAGE_ALIGN(buf) \ (char *) (((uintptr_t) (buf) + page_mask) & ~page_mask) @@ -752,9 +753,9 @@ static uint64_t do_io(struct thread_data *td) ((io_u->flags & IO_U_F_VER_LIST) || !td_rw(td))) { if (!td->o.verify_pattern_bytes) { - io_u->rand_seed = __rand(&td->__verify_state); + io_u->rand_seed = __rand(&td->verify_state); if (sizeof(int) != sizeof(long *)) - io_u->rand_seed *= __rand(&td->__verify_state); + io_u->rand_seed *= __rand(&td->verify_state); } if (td->o.verify_async) @@ -1344,7 +1345,6 @@ static void *thread_main(void *data) /* numa node setup */ if (o->numa_cpumask_set || o->numa_memmask_set) { struct bitmask *mask; - int ret; if (numa_available() < 0) { td_verror(td, errno, "Does not support NUMA API\n"); @@ -1484,18 +1484,21 @@ static void *thread_main(void *data) clear_state = 1; + fio_mutex_down(stat_mutex); if (td_read(td) && td->io_bytes[DDIR_READ]) { - elapsed = utime_since_now(&td->start); + elapsed = mtime_since_now(&td->start); td->ts.runtime[DDIR_READ] += elapsed; } if (td_write(td) && td->io_bytes[DDIR_WRITE]) { - elapsed = utime_since_now(&td->start); + elapsed = mtime_since_now(&td->start); td->ts.runtime[DDIR_WRITE] += elapsed; } if (td_trim(td) && td->io_bytes[DDIR_TRIM]) { - elapsed = utime_since_now(&td->start); + elapsed = mtime_since_now(&td->start); td->ts.runtime[DDIR_TRIM] += elapsed; } + fio_gettime(&td->start, NULL); + fio_mutex_up(stat_mutex); if (td->error || td->terminate) break; @@ -1511,16 +1514,16 @@ static void *thread_main(void *data) do_verify(td, verify_bytes); - td->ts.runtime[DDIR_READ] += utime_since_now(&td->start); + fio_mutex_down(stat_mutex); + td->ts.runtime[DDIR_READ] += mtime_since_now(&td->start); + fio_gettime(&td->start, NULL); + fio_mutex_up(stat_mutex); if (td->error || td->terminate) break; } update_rusage_stat(td); - td->ts.runtime[DDIR_READ] = (td->ts.runtime[DDIR_READ] + 999) / 1000; - td->ts.runtime[DDIR_WRITE] = (td->ts.runtime[DDIR_WRITE] + 999) / 1000; - td->ts.runtime[DDIR_TRIM] = (td->ts.runtime[DDIR_TRIM] + 999) / 1000; td->ts.total_run_time = mtime_since_now(&td->epoch); td->ts.io_bytes[DDIR_READ] = td->io_bytes[DDIR_READ]; td->ts.io_bytes[DDIR_WRITE] = td->io_bytes[DDIR_WRITE]; @@ -1553,9 +1556,9 @@ err: cgroup_shutdown(td, &cgroup_mnt); if (o->cpumask_set) { - int ret = fio_cpuset_exit(&o->cpumask); - - td_verror(td, ret, "fio_cpuset_exit"); + ret = fio_cpuset_exit(&o->cpumask); + if (ret) + td_verror(td, ret, "fio_cpuset_exit"); } /* @@ -1564,13 +1567,17 @@ err: if (o->write_iolog_file) write_iolog_close(td); - fio_mutex_remove(td->rusage_sem); - td->rusage_sem = NULL; - fio_mutex_remove(td->mutex); td->mutex = NULL; td_set_runstate(td, TD_EXITED); + + /* + * Do this last after setting our runstate to exited, so we + * know that the stat thread is signaled. + */ + check_update_rusage(td); + return (void *) (uintptr_t) td->error; } @@ -1972,23 +1979,23 @@ static void run_threads(void) update_io_ticks(); } -static void wait_for_disk_thread_exit(void) +static void wait_for_helper_thread_exit(void) { void *ret; - disk_util_start_exit(); - pthread_cond_signal(&du_cond); - pthread_join(disk_util_thread, &ret); + helper_exit = 1; + pthread_cond_signal(&helper_cond); + pthread_join(helper_thread, &ret); } static void free_disk_util(void) { disk_util_prune_entries(); - pthread_cond_destroy(&du_cond); + pthread_cond_destroy(&helper_cond); } -static void *disk_thread_main(void *data) +static void *helper_thread_main(void *data) { int ret = 0; @@ -2008,14 +2015,15 @@ static void *disk_thread_main(void *data) ts.tv_sec++; } - ret = pthread_cond_timedwait(&du_cond, &du_lock, &ts); - if (ret != ETIMEDOUT) { - printf("disk thread should exit %d\n", ret); - break; - } + pthread_cond_timedwait(&helper_cond, &helper_lock, &ts); ret = update_io_ticks(); + if (helper_do_stat) { + helper_do_stat = 0; + __show_running_run_stats(); + } + if (!is_backend) print_thread_status(); } @@ -2023,18 +2031,18 @@ static void *disk_thread_main(void *data) return NULL; } -static int create_disk_util_thread(void) +static int create_helper_thread(void) { int ret; setup_disk_util(); - pthread_cond_init(&du_cond, NULL); - pthread_mutex_init(&du_lock, NULL); + pthread_cond_init(&helper_cond, NULL); + pthread_mutex_init(&helper_lock, NULL); - ret = pthread_create(&disk_util_thread, NULL, disk_thread_main, NULL); + ret = pthread_create(&helper_thread, NULL, helper_thread_main, NULL); if (ret) { - log_err("Can't create disk util thread: %s\n", strerror(ret)); + log_err("Can't create helper thread: %s\n", strerror(ret)); return 1; } @@ -2074,20 +2082,18 @@ int fio_backend(void) set_genesis_time(); stat_init(); - create_disk_util_thread(); + create_helper_thread(); cgroup_list = smalloc(sizeof(*cgroup_list)); INIT_FLIST_HEAD(cgroup_list); run_threads(); - wait_for_disk_thread_exit(); + wait_for_helper_thread_exit(); if (!fio_abort) { __show_run_stats(); if (write_bw_log) { - int i; - for (i = 0; i < DDIR_RWDIR_CNT; i++) { struct io_log *log = agg_io_log[i]; @@ -2097,8 +2103,13 @@ int fio_backend(void) } } - for_each_td(td, i) + for_each_td(td, i) { fio_options_free(td); + if (td->rusage_sem) { + fio_mutex_remove(td->rusage_sem); + td->rusage_sem = NULL; + } + } free_disk_util(); cgroup_kill(cgroup_list);