Merge branch 'fiopr_compressfixes' of https://github.com/PCPartPicker/fio
[fio.git] / stat.c
diff --git a/stat.c b/stat.c
index a6810d9b653171705193fe126e16d319b5029edd..949af5edd49ffa05dfa16bbef70c7d1037de8261 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -1,5 +1,6 @@
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 #include <sys/time.h>
 #include <sys/stat.h>
 #include <math.h>
@@ -377,7 +378,7 @@ void show_group_stats(struct group_run_stats *rs, struct buf_output *out)
                free(maxalt);
        }
 
-       /* Need to aggregate statisitics to show mixed values */
+       /* Need to aggregate statistics to show mixed values */
        if (rs->unified_rw_rep == UNIFIED_BOTH)
                show_mixed_group_stats(rs, out);
 }
@@ -1493,25 +1494,37 @@ static void add_ddir_status_json(struct thread_stat *ts,
        if (!ddir_rw(ddir))
                return;
 
-       /* Only print PRIO latencies if some high priority samples were gathered */
-       if (ts->clat_high_prio_stat[ddir].samples > 0) {
-               const char *high, *low;
+       /* Only include per prio stats if there are >= 2 prios with samples */
+       if (get_nr_prios_with_samples(ts, ddir) >= 2) {
+               struct json_array *array = json_create_array();
+               const char *obj_name;
+               int i;
 
-               if (ts->lat_percentiles) {
-                       high = "lat_high_prio";
-                       low = "lat_low_prio";
-               } else {
-                       high = "clat_high_prio";
-                       low = "clat_low_prio";
-               }
+               if (ts->lat_percentiles)
+                       obj_name = "lat_ns";
+               else
+                       obj_name = "clat_ns";
 
-               tmp_object = add_ddir_lat_json(ts, ts->clat_percentiles | ts->lat_percentiles,
-                               &ts->clat_high_prio_stat[ddir], ts->io_u_plat_high_prio[ddir]);
-               json_object_add_value_object(dir_object, high, tmp_object);
+               json_object_add_value_array(dir_object, "prios", array);
 
-               tmp_object = add_ddir_lat_json(ts, ts->clat_percentiles | ts->lat_percentiles,
-                               &ts->clat_low_prio_stat[ddir], ts->io_u_plat_low_prio[ddir]);
-               json_object_add_value_object(dir_object, low, tmp_object);
+               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);
+                       }
+               }
        }
 
        if (calc_lat(&ts->bw_stat[ddir], &min, &max, &mean, &dev)) {
@@ -1686,6 +1699,7 @@ static struct json_object *show_thread_status_json(struct thread_stat *ts,
        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)
@@ -2029,6 +2043,9 @@ void free_clat_prio_stats(struct thread_stat *ts)
 {
        enum fio_ddir ddir;
 
+       if (!ts)
+               return;
+
        for (ddir = 0; ddir < DDIR_RWDIR_CNT; ddir++) {
                sfree(ts->clat_prio[ddir]);
                ts->clat_prio[ddir] = NULL;
@@ -2716,6 +2733,9 @@ int __show_running_run_stats(void)
        fio_gettime(&ts, NULL);
 
        for_each_td(td, i) {
+               if (td->runstate >= TD_EXITED)
+                       continue;
+
                td->update_rusage = 1;
                for_each_rw_ddir(ddir) {
                        td->ts.io_bytes[ddir] = td->io_bytes[ddir];
@@ -2744,6 +2764,9 @@ int __show_running_run_stats(void)
        __show_run_stats();
 
        for_each_td(td, i) {
+               if (td->runstate >= TD_EXITED)
+                       continue;
+
                if (td_read(td) && td->ts.io_bytes[DDIR_READ])
                        td->ts.runtime[DDIR_READ] -= rt[i];
                if (td_write(td) && td->ts.io_bytes[DDIR_WRITE])
@@ -3005,7 +3028,7 @@ static void __add_log_sample(struct io_log *iolog, union io_sample_data data,
                s = get_sample(iolog, cur_log, cur_log->nr_samples);
 
                s->data = data;
-               s->time = t + (iolog->td ? iolog->td->unix_epoch : 0);
+               s->time = t + (iolog->td ? iolog->td->alternate_epoch : 0);
                io_sample_set_ddir(iolog, s, ddir);
                s->bs = bs;
                s->priority = priority;