stat: use long doubles to identify latency percentiles
[fio.git] / stat.c
diff --git a/stat.c b/stat.c
index 351c49cc4f720024a7b500b525e9a32657e65299..66a13bcad4347269f7532669027d3644c72ef040 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -139,7 +139,6 @@ unsigned int calc_clat_percentiles(uint64_t *io_u_plat, unsigned long long nr,
 {
        unsigned long long sum = 0;
        unsigned int len, i, j = 0;
-       unsigned int oval_len = 0;
        unsigned long long *ovals = NULL;
        bool is_last;
 
@@ -161,20 +160,19 @@ unsigned int calc_clat_percentiles(uint64_t *io_u_plat, unsigned long long nr,
        if (len > 1)
                qsort((void *)plist, len, sizeof(plist[0]), double_cmp);
 
+       ovals = malloc(len * sizeof(*ovals));
+       if (!ovals)
+               return 0;
+
        /*
         * Calculate bucket values, note down max and min values
         */
        is_last = false;
        for (i = 0; i < FIO_IO_U_PLAT_NR && !is_last; i++) {
                sum += io_u_plat[i];
-               while (sum >= (plist[j].u.f / 100.0 * nr)) {
+               while (sum >= ((long double) plist[j].u.f / 100.0 * nr)) {
                        assert(plist[j].u.f <= 100.0);
 
-                       if (j == oval_len) {
-                               oval_len += 100;
-                               ovals = realloc(ovals, oval_len * sizeof(*ovals));
-                       }
-
                        ovals[j] = plat_idx_to_val(i);
                        if (ovals[j] < *minv)
                                *minv = ovals[j];
@@ -189,6 +187,9 @@ unsigned int calc_clat_percentiles(uint64_t *io_u_plat, unsigned long long nr,
                }
        }
 
+       if (!is_last)
+               log_err("fio: error calculating latency percentiles\n");
+
        *output = ovals;
        return len;
 }
@@ -1090,7 +1091,8 @@ static void add_ddir_status_json(struct thread_stat *ts,
                len = 0;
 
        percentile_object = json_create_object();
-       json_object_add_value_object(tmp_object, "percentile", percentile_object);
+       if (ts->clat_percentiles)
+               json_object_add_value_object(tmp_object, "percentile", percentile_object);
        for (i = 0; i < len; i++) {
                snprintf(buf, sizeof(buf), "%f", ts->percentile_list[i].u.f);
                json_object_add_value_int(percentile_object, (const char *)buf, ovals[i]);
@@ -1129,6 +1131,8 @@ static void add_ddir_status_json(struct thread_stat *ts,
        json_object_add_value_int(tmp_object, "max", max);
        json_object_add_value_float(tmp_object, "mean", mean);
        json_object_add_value_float(tmp_object, "stddev", dev);
+       if (ts->lat_percentiles)
+               json_object_add_value_object(tmp_object, "percentile", percentile_object);
        if (output_format & FIO_OUTPUT_JSON_PLUS && ts->lat_percentiles)
                json_object_add_value_object(tmp_object, "bins", clat_bins_object);