X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=stat.c;h=ee495ffd88dc5dae82f92717deda18e59ef8bd57;hp=0fd8b72587e6eef5882f3041d1db04b40bbb2ca4;hb=fb390e242cac8868e01cdc2046c63e04e3d53d70;hpb=e5bd13470beaeed9c4a6835b7b92265fb94173a9 diff --git a/stat.c b/stat.c index 0fd8b725..ee495ffd 100644 --- a/stat.c +++ b/stat.c @@ -63,12 +63,12 @@ static unsigned int plat_val_to_idx(unsigned int val) /* * Discard the error bits and apply the mask to find the - * index for the buckets in the group + * index for the buckets in the group */ offset = (FIO_IO_U_PLAT_VAL - 1) & (val >> error_bits); /* Make sure the index does not exceed (array size - 1) */ - idx = (base + offset) < (FIO_IO_U_PLAT_NR - 1)? + idx = (base + offset) < (FIO_IO_U_PLAT_NR - 1) ? (base + offset) : (FIO_IO_U_PLAT_NR - 1); return idx; @@ -86,11 +86,11 @@ static unsigned int plat_idx_to_val(unsigned int idx) /* MSB <= (FIO_IO_U_PLAT_BITS-1), cannot be rounded off. Use * all bits of the sample as index */ - if (idx < (FIO_IO_U_PLAT_VAL << 1) ) + if (idx < (FIO_IO_U_PLAT_VAL << 1)) return idx; /* Find the group and compute the minimum value of that group */ - error_bits = (idx >> FIO_IO_U_PLAT_BITS) -1; + error_bits = (idx >> FIO_IO_U_PLAT_BITS) - 1; base = 1 << (error_bits + FIO_IO_U_PLAT_BITS); /* Find its bucket number of the group */ @@ -140,7 +140,7 @@ unsigned int calc_clat_percentiles(unsigned int *io_u_plat, unsigned long nr, * isn't a worry. Also note that this does not work for NaN values. */ if (len > 1) - qsort((void*)plist, len, sizeof(plist[0]), double_cmp); + qsort((void *)plist, len, sizeof(plist[0]), double_cmp); /* * Calculate bucket values, note down max and min values @@ -285,11 +285,7 @@ void show_group_stats(struct group_run_stats *rs) } } -#define ts_total_io_u(ts) \ - ((ts)->total_io_u[0] + (ts)->total_io_u[1]) - -static void stat_calc_dist(unsigned int *map, unsigned long total, - double *io_u_dist) +void stat_calc_dist(unsigned int *map, unsigned long total, double *io_u_dist) { int i; @@ -577,7 +573,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; } @@ -633,7 +629,7 @@ static void show_ddir_status_terse(struct thread_stat *ts, } static void show_thread_status_terse_v2(struct thread_stat *ts, - struct group_run_stats *rs) + 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]; @@ -746,11 +742,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, @@ -960,6 +957,11 @@ void show_run_stats(void) else memset(ts->description, 0, FIO_JOBNAME_SIZE); + /* + * If multiple entries in this group, this is + * the first member. + */ + ts->thread_number = td->thread_number; ts->groupid = td->groupid; /* @@ -1008,10 +1010,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; @@ -1023,16 +1026,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]; } /* @@ -1068,12 +1067,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;