Add support for multiple output formats
[fio.git] / eta.c
diff --git a/eta.c b/eta.c
index bdd537633fff90ff15f07806e632227f0ef6c132..ba066546bcd485552032eeb1d9d2eba1488c86b0 100644 (file)
--- a/eta.c
+++ b/eta.c
@@ -6,41 +6,27 @@
 #include <string.h>
 
 #include "fio.h"
+#include "lib/pow2.h"
 
 static char __run_str[REAL_MAX_JOBS + 1];
 static char run_str[__THREAD_RUNSTR_SZ(REAL_MAX_JOBS)];
 
-static void update_condensed_str(char *run_str, char *run_str_condensed)
+static void update_condensed_str(char *rstr, char *run_str_condensed)
 {
-       int i, ci, last, nr;
-       size_t len;
-
-       len = strlen(run_str);
-       if (!len)
-               return;
-
-       last = 0;
-       nr = 0;
-       ci = 0;
-       for (i = 0; i < len; i++) {
-               if (!last) {
-new:
-                       run_str_condensed[ci] = run_str[i];
-                       last = run_str[i];
-                       nr = 1;
-                       ci++;
-               } else if (last == run_str[i]) {
-                       nr++;
-               } else {
-                       ci += sprintf(&run_str_condensed[ci], "(%u),", nr);
-                       goto new;
+       if (*rstr) {
+               while (*rstr) {
+                       int nr = 1;
+
+                       *run_str_condensed++ = *rstr++;
+                       while (*(rstr - 1) == *rstr) {
+                               rstr++;
+                               nr++;
+                       }
+                       run_str_condensed += sprintf(run_str_condensed, "(%u),", nr);
                }
+               run_str_condensed--;
        }
-
-       if (nr)
-               ci += sprintf(&run_str_condensed[ci], "(%u)", nr);
-
-       run_str_condensed[ci + 1] = '\0';
+       *run_str_condensed = '\0';
 }
 
 /*
@@ -137,6 +123,11 @@ void eta_to_str(char *str, unsigned long eta_sec)
        unsigned int d, h, m, s;
        int disp_hour = 0;
 
+       if (eta_sec == -1) {
+               sprintf(str, "--");
+               return;
+       }
+
        s = eta_sec % 60;
        eta_sec /= 60;
        m = eta_sec % 60;
@@ -160,7 +151,7 @@ void eta_to_str(char *str, unsigned long eta_sec)
 /*
  * Best effort calculation of the estimated pending runtime of a job.
  */
-static int thread_eta(struct thread_data *td)
+static unsigned long thread_eta(struct thread_data *td)
 {
        unsigned long long bytes_total, bytes_done;
        unsigned long eta_sec = 0;
@@ -172,6 +163,9 @@ static int thread_eta(struct thread_data *td)
 
        bytes_total = td->total_io_size;
 
+       if (td->flags & TD_F_NO_PROGRESS)
+               return -1;
+
        if (td->o.fill_device && td->o.size  == -1ULL) {
                if (!td->fill_device_size || td->fill_device_size == -1ULL)
                        return 0;
@@ -249,11 +243,11 @@ static int thread_eta(struct thread_data *td)
                 * if given, otherwise assume it'll run at the specified rate.
                 */
                if (td->o.timeout) {
-                       uint64_t timeout = td->o.timeout;
+                       uint64_t __timeout = td->o.timeout;
                        uint64_t start_delay = td->o.start_delay;
                        uint64_t ramp_time = td->o.ramp_time;
 
-                       t_eta = timeout + start_delay + ramp_time;
+                       t_eta = __timeout + start_delay + ramp_time;
                        t_eta /= 1000000ULL;
 
                        if (in_ramp_time(td)) {
@@ -296,14 +290,19 @@ static void calc_rate(int unified_rw_rep, unsigned long mtime,
        int i;
 
        for (i = 0; i < DDIR_RWDIR_CNT; i++) {
-               unsigned long long diff;
+               unsigned long long diff, this_rate;
 
                diff = io_bytes[i] - prev_io_bytes[i];
+               if (mtime)
+                       this_rate = ((1000 * diff) / mtime) / 1024;
+               else
+                       this_rate = 0;
+
                if (unified_rw_rep) {
                        rate[i] = 0;
-                       rate[0] += ((1000 * diff) / mtime) / 1024;
+                       rate[0] += this_rate;
                } else
-                       rate[i] = ((1000 * diff) / mtime) / 1024;
+                       rate[i] = this_rate;
 
                prev_io_bytes[i] = io_bytes[i];
        }
@@ -316,14 +315,19 @@ static void calc_iops(int unified_rw_rep, unsigned long mtime,
        int i;
 
        for (i = 0; i < DDIR_RWDIR_CNT; i++) {
-               unsigned long long diff;
+               unsigned long long diff, this_iops;
 
                diff = io_iops[i] - prev_io_iops[i];
+               if (mtime)
+                       this_iops = (diff * 1000) / mtime;
+               else
+                       this_iops = 0;
+
                if (unified_rw_rep) {
                        iops[i] = 0;
-                       iops[0] += (diff * 1000) / mtime;
+                       iops[0] += this_iops;
                } else
-                       iops[i] = (diff * 1000) / mtime;
+                       iops[i] = this_iops;
 
                prev_io_iops[i] = io_iops[i];
        }
@@ -348,7 +352,7 @@ int calc_thread_status(struct jobs_eta *je, int force)
        static struct timeval rate_prev_time, disp_prev_time;
 
        if (!force) {
-               if (output_format != FIO_OUTPUT_NORMAL &&
+               if (!(output_format & FIO_OUTPUT_NORMAL) &&
                    f_out == stdout)
                        return 0;
                if (temp_stall_ts || eta_print == FIO_ETA_NEVER)
@@ -407,10 +411,9 @@ int calc_thread_status(struct jobs_eta *je, int force)
                } else if (td->runstate == TD_RAMP) {
                        je->nr_running++;
                        je->nr_ramp++;
-               } else if (td->runstate == TD_SETTING_UP) {
-                       je->nr_running++;
+               } else if (td->runstate == TD_SETTING_UP)
                        je->nr_setting_up++;
-               else if (td->runstate < TD_RUNNING)
+               else if (td->runstate < TD_RUNNING)
                        je->nr_pending++;
 
                if (je->elapsed_sec >= 3)
@@ -528,7 +531,8 @@ void display_thread_status(struct jobs_eta *je)
                int l;
                int ddir;
 
-               if ((!je->eta_sec && !eta_good) || je->nr_ramp == je->nr_running)
+               if ((!je->eta_sec && !eta_good) || je->nr_ramp == je->nr_running ||
+                   je->eta_sec == -1)
                        strcpy(perc_str, "-.-% done");
                else {
                        double mult = 100.0;
@@ -571,8 +575,7 @@ void display_thread_status(struct jobs_eta *je)
        if (!eta_new_line_init) {
                fio_gettime(&disp_eta_new_line, NULL);
                eta_new_line_init = 1;
-       } else if (eta_new_line &&
-                  mtime_since_now(&disp_eta_new_line) > eta_new_line * 1000) {
+       } else if (eta_new_line && mtime_since_now(&disp_eta_new_line) > eta_new_line) {
                fio_gettime(&disp_eta_new_line, NULL);
                eta_new_line_pending = 1;
        }
@@ -587,15 +590,18 @@ struct jobs_eta *get_jobs_eta(int force, size_t *size)
        if (!thread_number)
                return NULL;
 
-       *size = sizeof(*je) + THREAD_RUNSTR_SZ;
+       *size = sizeof(*je) + THREAD_RUNSTR_SZ + 1;
        je = malloc(*size);
+       if (!je)
+               return NULL;
        memset(je, 0, *size);
 
-       if (!calc_thread_status(je, 0)) {
+       if (!calc_thread_status(je, force)) {
                free(je);
                return NULL;
        }
 
+       *size = sizeof(*je) + strlen((char *) je->run_str) + 1;
        return je;
 }