X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=stat.c;h=0a0479814825c7a5c6eaf09985bc8eb9b15b496c;hp=7e3b97966c0b7754cdb10333ffa341a0adf26a5e;hb=b2cecdc28469f8042d6cc3d83d83b18086845f18;hpb=2f2c69242ba72508fb5429d12e1fd72c3cc1e76c diff --git a/stat.c b/stat.c index 7e3b9796..0a047981 100644 --- a/stat.c +++ b/stat.c @@ -523,19 +523,25 @@ void show_thread_status(struct thread_stat *ts, struct group_run_stats *rs) double io_u_dist[FIO_IO_U_MAP_NR]; double io_u_lat_u[FIO_IO_U_LAT_U_NR]; double io_u_lat_m[FIO_IO_U_LAT_M_NR]; + time_t time_p; + char time_buf[64]; if (!(ts->io_bytes[0] + ts->io_bytes[1]) && !(ts->total_io_u[0] + ts->total_io_u[1])) return; + time(&time_p); + ctime_r((const time_t *) &time_p, time_buf); + if (!ts->error) { - log_info("%s: (groupid=%d, jobs=%d): err=%2d: pid=%d\n", + log_info("%s: (groupid=%d, jobs=%d): err=%2d: pid=%d: %s", ts->name, ts->groupid, ts->members, - ts->error, (int) ts->pid); + ts->error, (int) ts->pid, time_buf); } else { - log_info("%s: (groupid=%d, jobs=%d): err=%2d (%s): pid=%d\n", + log_info("%s: (groupid=%d, jobs=%d): err=%2d (%s): pid=%d: %s", ts->name, ts->groupid, ts->members, - ts->error, ts->verror, (int) ts->pid); + ts->error, ts->verror, (int) ts->pid, + time_buf); } if (strlen(ts->description)) @@ -613,7 +619,7 @@ static void show_ddir_status_terse(struct thread_stat *ts, if (ts->runtime[ddir]) { uint64_t runt = ts->runtime[ddir]; - bw = ts->io_bytes[ddir] / runt; + bw = ((1000 * ts->io_bytes[ddir]) / runt) / 1024; iops = (1000 * (uint64_t) ts->total_io_u[ddir]) / runt; } @@ -782,11 +788,12 @@ static void show_thread_status_terse_v3(struct thread_stat *ts, /* Additional output if continue_on_error set - default off*/ if (ts->continue_on_error) log_info(";%lu;%d", ts->total_err_count, ts->first_error); - log_info("\n"); /* Additional output if description is set */ if (strlen(ts->description)) log_info(";%s", ts->description); + + log_info("\n"); } static void show_thread_status_terse(struct thread_stat *ts, @@ -1044,10 +1051,11 @@ void show_run_stats(void) bw = 0; if (ts->runtime[j]) { - unsigned long runt; + unsigned long runt = ts->runtime[j]; + unsigned long long kb; - runt = ts->runtime[j]; - bw = ts->io_bytes[j] / runt; + kb = ts->io_bytes[j] / rs->kb_base; + bw = kb * 1000 / runt; } if (bw < rs->min_bw[j]) rs->min_bw[j] = bw; @@ -1059,16 +1067,12 @@ void show_run_stats(void) } for (i = 0; i < groupid + 1; i++) { - unsigned long max_run[2]; - rs = &runstats[i]; - max_run[0] = rs->max_run[0]; - max_run[1] = rs->max_run[1]; if (rs->max_run[0]) - rs->agg[0] = (rs->io_kb[0] * 1000) / max_run[0]; + rs->agg[0] = (rs->io_kb[0] * 1000) / rs->max_run[0]; if (rs->max_run[1]) - rs->agg[1] = (rs->io_kb[1] * 1000) / max_run[1]; + rs->agg[1] = (rs->io_kb[1] * 1000) / rs->max_run[1]; } /* @@ -1104,12 +1108,59 @@ void show_run_stats(void) else if (!terse_output) show_disk_util(0); - free_disk_util(); - free(runstats); free(threadstats); } +static void *__show_running_run_stats(void *arg) +{ + struct thread_data *td; + unsigned long long *rt; + struct timeval tv; + int i; + + rt = malloc(thread_number * sizeof(unsigned long long)); + fio_gettime(&tv, NULL); + + for_each_td(td, i) { + rt[i] = mtime_since(&td->start, &tv); + if (td_read(td) && td->io_bytes[DDIR_READ]) + td->ts.runtime[DDIR_READ] += rt[i]; + if (td_write(td) && td->io_bytes[DDIR_WRITE]) + td->ts.runtime[DDIR_WRITE] += rt[i]; + + update_rusage_stat(td); + td->ts.io_bytes[0] = td->io_bytes[0]; + td->ts.io_bytes[1] = td->io_bytes[1]; + td->ts.total_run_time = mtime_since(&td->epoch, &tv); + } + + show_run_stats(); + + for_each_td(td, i) { + if (td_read(td) && td->io_bytes[DDIR_READ]) + td->ts.runtime[DDIR_READ] -= rt[i]; + if (td_write(td) && td->io_bytes[DDIR_WRITE]) + td->ts.runtime[DDIR_WRITE] -= rt[i]; + } + + free(rt); + return NULL; +} + +/* + * Called from signal handler. It _should_ be safe to just run this inline + * in the sig handler, but we should be disturbing the system less by just + * creating a thread to do it. + */ +void show_running_run_stats(void) +{ + pthread_t thread; + + pthread_create(&thread, NULL, __show_running_run_stats, NULL); + pthread_detach(thread); +} + static inline void add_stat_sample(struct io_stat *is, unsigned long data) { double val = data; @@ -1292,15 +1343,26 @@ void add_bw_sample(struct thread_data *td, enum fio_ddir ddir, unsigned int bs, if (spent < td->o.bw_avg_time) return; - rate = (td->this_io_bytes[ddir] - td->stat_io_bytes[ddir]) * - 1000 / spent / 1024; - add_stat_sample(&ts->bw_stat[ddir], rate); + /* + * Compute both read and write rates for the interval. + */ + for (ddir = DDIR_READ; ddir <= DDIR_WRITE; ddir++) { + uint64_t delta; + + delta = td->this_io_bytes[ddir] - td->stat_io_bytes[ddir]; + if (!delta) + continue; /* No entries for interval */ + + rate = delta * 1000 / spent / 1024; + add_stat_sample(&ts->bw_stat[ddir], rate); - if (td->bw_log) - add_log_sample(td, td->bw_log, rate, ddir, bs); + if (td->bw_log) + add_log_sample(td, td->bw_log, rate, ddir, bs); + + td->stat_io_bytes[ddir] = td->this_io_bytes[ddir]; + } fio_gettime(&td->bw_sample_time, NULL); - td->stat_io_bytes[ddir] = td->this_io_bytes[ddir]; } void add_iops_sample(struct thread_data *td, enum fio_ddir ddir, @@ -1316,13 +1378,24 @@ void add_iops_sample(struct thread_data *td, enum fio_ddir ddir, if (spent < td->o.iops_avg_time) return; - iops = ((td->this_io_blocks[ddir] - td->stat_io_blocks[ddir]) * 1000) / spent; + /* + * Compute both read and write rates for the interval. + */ + for (ddir = DDIR_READ; ddir <= DDIR_WRITE; ddir++) { + uint64_t delta; + + delta = td->this_io_blocks[ddir] - td->stat_io_blocks[ddir]; + if (!delta) + continue; /* No entries for interval */ - add_stat_sample(&ts->iops_stat[ddir], iops); + iops = (delta * 1000) / spent; + add_stat_sample(&ts->iops_stat[ddir], iops); - if (td->iops_log) - add_log_sample(td, td->iops_log, iops, ddir, 0); + if (td->iops_log) + add_log_sample(td, td->iops_log, iops, ddir, 0); + + td->stat_io_blocks[ddir] = td->this_io_blocks[ddir]; + } fio_gettime(&td->iops_sample_time, NULL); - td->stat_io_blocks[ddir] = td->this_io_blocks[ddir]; }