#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <math.h>
iops = (1000 * (uint64_t)ts->total_io_u[ddir]) / runt;
iops_p = num2str(iops, ts->sig_figs, 1, 0, N2S_NONE);
- if (ddir == DDIR_WRITE)
+ if (ddir == DDIR_WRITE || ddir == DDIR_TRIM)
post_st = zbd_write_status(ts);
else if (ddir == DDIR_READ && ts->cachehit && ts->cachemiss) {
uint64_t total;
/* Only print per prio stats if there are >= 2 prios with samples */
if (get_nr_prios_with_samples(ts, ddir) >= 2) {
for (i = 0; i < ts->nr_clat_prio[ddir]; i++) {
- if (calc_lat(&ts->clat_prio[ddir][i].clat_stat, &min,
- &max, &mean, &dev)) {
- char buf[64];
+ char buf[64];
- snprintf(buf, sizeof(buf),
- "%s prio %u/%u",
- clat_type,
- ts->clat_prio[ddir][i].ioprio >> 13,
- ts->clat_prio[ddir][i].ioprio & 7);
- display_lat(buf, min, max, mean, dev, out);
- }
+ if (!calc_lat(&ts->clat_prio[ddir][i].clat_stat, &min,
+ &max, &mean, &dev))
+ continue;
+
+ snprintf(buf, sizeof(buf),
+ "%s prio %u/%u",
+ clat_type,
+ ioprio_class(ts->clat_prio[ddir][i].ioprio),
+ ioprio(ts->clat_prio[ddir][i].ioprio));
+ display_lat(buf, min, max, mean, dev, out);
}
}
/* Only print per prio stats if there are >= 2 prios with samples */
if (get_nr_prios_with_samples(ts, ddir) >= 2) {
for (i = 0; i < ts->nr_clat_prio[ddir]; i++) {
- uint64_t prio_samples = ts->clat_prio[ddir][i].clat_stat.samples;
-
- if (prio_samples > 0) {
- snprintf(prio_name, sizeof(prio_name),
- "%s prio %u/%u (%.2f%% of IOs)",
- clat_type,
- ts->clat_prio[ddir][i].ioprio >> 13,
- ts->clat_prio[ddir][i].ioprio & 7,
- 100. * (double) prio_samples / (double) samples);
- show_clat_percentiles(ts->clat_prio[ddir][i].io_u_plat,
- prio_samples, ts->percentile_list,
- ts->percentile_precision,
- prio_name, out);
- }
+ uint64_t prio_samples =
+ ts->clat_prio[ddir][i].clat_stat.samples;
+
+ if (!prio_samples)
+ continue;
+
+ snprintf(prio_name, sizeof(prio_name),
+ "%s prio %u/%u (%.2f%% of IOs)",
+ clat_type,
+ ioprio_class(ts->clat_prio[ddir][i].ioprio),
+ ioprio(ts->clat_prio[ddir][i].ioprio),
+ 100. * (double) prio_samples / (double) samples);
+ show_clat_percentiles(ts->clat_prio[ddir][i].io_u_plat,
+ prio_samples, ts->percentile_list,
+ ts->percentile_precision,
+ prio_name, out);
}
}
}
json_object_add_value_array(dir_object, "prios", array);
for (i = 0; i < ts->nr_clat_prio[ddir]; i++) {
- if (ts->clat_prio[ddir][i].clat_stat.samples > 0) {
- struct json_object *obj = json_create_object();
- unsigned long long class, level;
-
- class = ts->clat_prio[ddir][i].ioprio >> 13;
- json_object_add_value_int(obj, "prioclass", class);
- level = ts->clat_prio[ddir][i].ioprio & 7;
- json_object_add_value_int(obj, "prio", level);
-
- tmp_object = add_ddir_lat_json(ts,
- ts->clat_percentiles | ts->lat_percentiles,
- &ts->clat_prio[ddir][i].clat_stat,
- ts->clat_prio[ddir][i].io_u_plat);
- json_object_add_value_object(obj, obj_name, tmp_object);
- json_array_add_value_object(array, obj);
- }
+ struct json_object *obj;
+
+ if (!ts->clat_prio[ddir][i].clat_stat.samples)
+ continue;
+
+ obj = json_create_object();
+
+ json_object_add_value_int(obj, "prioclass",
+ ioprio_class(ts->clat_prio[ddir][i].ioprio));
+ json_object_add_value_int(obj, "prio",
+ ioprio(ts->clat_prio[ddir][i].ioprio));
+
+ tmp_object = add_ddir_lat_json(ts,
+ ts->clat_percentiles | ts->lat_percentiles,
+ &ts->clat_prio[ddir][i].clat_stat,
+ ts->clat_prio[ddir][i].io_u_plat);
+ json_object_add_value_object(obj, obj_name, tmp_object);
+ json_array_add_value_object(array, obj);
}
}
if (je) {
json_object_add_value_int(root, "eta", je->eta_sec);
json_object_add_value_int(root, "elapsed", je->elapsed_sec);
+ free(je);
}
if (opt_list)
struct json_array *iops, *bw;
int j, k, l;
char ss_buf[64];
+ int intervals = ts->ss_dur / (ss_check_interval / 1000L);
snprintf(ss_buf, sizeof(ss_buf), "%s%s:%f%s",
ts->ss_state & FIO_SS_IOPS ? "iops" : "bw",
if ((ts->ss_state & FIO_SS_ATTAINED) || !(ts->ss_state & FIO_SS_BUFFER_FULL))
j = ts->ss_head;
else
- j = ts->ss_head == 0 ? ts->ss_dur - 1 : ts->ss_head - 1;
- for (l = 0; l < ts->ss_dur; l++) {
- k = (j + l) % ts->ss_dur;
+ j = ts->ss_head == 0 ? intervals - 1 : ts->ss_head - 1;
+ for (l = 0; l < intervals; l++) {
+ k = (j + l) % intervals;
json_array_add_value_int(bw, ts->ss_bw_data[k]);
json_array_add_value_int(iops, ts->ss_iops_data[k]);
}
static void init_per_prio_stats(struct thread_stat *threadstats, int nr_ts)
{
- struct thread_data *td;
struct thread_stat *ts;
int i, j, last_ts, idx;
enum fio_ddir ddir;
* store a 1 in ts->disable_prio_stat, and then do an additional
* loop at the end where we invert the ts->disable_prio_stat values.
*/
- for_each_td(td, i) {
+ for_each_td(td) {
if (!td->o.stats)
continue;
if (idx &&
}
idx++;
- }
+ } end_for_each();
/* Loop through all dst threadstats and fixup the values. */
for (i = 0; i < nr_ts; i++) {
void __show_run_stats(void)
{
struct group_run_stats *runstats, *rs;
- struct thread_data *td;
struct thread_stat *threadstats, *ts;
int i, j, k, nr_ts, last_ts, idx;
bool kb_base_warned = false;
*/
nr_ts = 0;
last_ts = -1;
- for_each_td(td, i) {
+ for_each_td(td) {
if (!td->o.group_reporting) {
nr_ts++;
continue;
last_ts = td->groupid;
nr_ts++;
- }
+ } end_for_each();
threadstats = malloc(nr_ts * sizeof(struct thread_stat));
opt_lists = malloc(nr_ts * sizeof(struct flist_head *));
j = 0;
last_ts = -1;
idx = 0;
- for_each_td(td, i) {
+ for_each_td(td) {
if (!td->o.stats)
continue;
if (idx && (!td->o.group_reporting ||
}
else
ts->ss_dur = ts->ss_state = 0;
- }
+ } end_for_each();
for (i = 0; i < nr_ts; i++) {
unsigned long long bw;
int __show_running_run_stats(void)
{
- struct thread_data *td;
unsigned long long *rt;
struct timespec ts;
- int i;
fio_sem_down(stat_sem);
rt = malloc(thread_number * sizeof(unsigned long long));
fio_gettime(&ts, NULL);
- for_each_td(td, i) {
+ for_each_td(td) {
if (td->runstate >= TD_EXITED)
continue;
}
td->ts.total_run_time = mtime_since(&td->epoch, &ts);
- rt[i] = mtime_since(&td->start, &ts);
+ rt[__td_index] = mtime_since(&td->start, &ts);
if (td_read(td) && td->ts.io_bytes[DDIR_READ])
- td->ts.runtime[DDIR_READ] += rt[i];
+ td->ts.runtime[DDIR_READ] += rt[__td_index];
if (td_write(td) && td->ts.io_bytes[DDIR_WRITE])
- td->ts.runtime[DDIR_WRITE] += rt[i];
+ td->ts.runtime[DDIR_WRITE] += rt[__td_index];
if (td_trim(td) && td->ts.io_bytes[DDIR_TRIM])
- td->ts.runtime[DDIR_TRIM] += rt[i];
- }
+ td->ts.runtime[DDIR_TRIM] += rt[__td_index];
+ } end_for_each();
- for_each_td(td, i) {
+ for_each_td(td) {
if (td->runstate >= TD_EXITED)
continue;
if (td->rusage_sem) {
fio_sem_down(td->rusage_sem);
}
td->update_rusage = 0;
- }
+ } end_for_each();
__show_run_stats();
- for_each_td(td, i) {
+ for_each_td(td) {
if (td->runstate >= TD_EXITED)
continue;
if (td_read(td) && td->ts.io_bytes[DDIR_READ])
- td->ts.runtime[DDIR_READ] -= rt[i];
+ td->ts.runtime[DDIR_READ] -= rt[__td_index];
if (td_write(td) && td->ts.io_bytes[DDIR_WRITE])
- td->ts.runtime[DDIR_WRITE] -= rt[i];
+ td->ts.runtime[DDIR_WRITE] -= rt[__td_index];
if (td_trim(td) && td->ts.io_bytes[DDIR_TRIM])
- td->ts.runtime[DDIR_TRIM] -= rt[i];
- }
+ td->ts.runtime[DDIR_TRIM] -= rt[__td_index];
+ } end_for_each();
free(rt);
fio_sem_up(stat_sem);
* forever
*/
if (!iolog->cur_log_max) {
- new_samples = iolog->td->o.log_entries;
+ if (iolog->td)
+ new_samples = iolog->td->o.log_entries;
+ else
+ new_samples = DEF_LOG_ENTRIES;
} else {
new_samples = iolog->cur_log_max * 2;
if (new_samples > MAX_LOG_ENTRIES)
*/
int calc_log_samples(void)
{
- struct thread_data *td;
unsigned int next = ~0U, tmp = 0, next_mod = 0, log_avg_msec_min = -1U;
struct timespec now;
- int i;
long elapsed_time = 0;
fio_gettime(&now, NULL);
- for_each_td(td, i) {
+ for_each_td(td) {
elapsed_time = mtime_since_now(&td->epoch);
if (!td->o.stats)
if (tmp < next)
next = tmp;
- }
+ } end_for_each();
/* if log_avg_msec_min has not been changed, set it to 0 */
if (log_avg_msec_min == -1U)