#include "fio.h"
-static char run_str[REAL_MAX_JOBS + 1];
+static char __run_str[REAL_MAX_JOBS + 1];
+
+/*
+ * Worst level condensing would be 1:4, so allow enough room for that
+ */
+static char run_str[(4 * REAL_MAX_JOBS) + 1];
+
+static void update_condensed_str(char *run_str, 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 {
+ int elen;
+
+ elen = sprintf(&run_str_condensed[ci], "(%u),", nr);
+ ci += elen;
+ goto new;
+ }
+ }
+
+ if (nr)
+ sprintf(&run_str_condensed[ci], "(%u)", nr);
+}
+
/*
* Sets the status of the 'td' in the printed status map.
*/
static void check_str_update(struct thread_data *td)
{
- char c = run_str[td->thread_number - 1];
+ char c = __run_str[td->thread_number - 1];
switch (td->runstate) {
case TD_REAPED:
log_err("state %d\n", td->runstate);
}
- run_str[td->thread_number - 1] = c;
+ __run_str[td->thread_number - 1] = c;
+ update_condensed_str(__run_str, run_str);
}
/*
double perc, perc_t;
bytes_done = ddir_rw_sum(td->io_bytes);
- perc = (double) bytes_done / (double) bytes_total;
- if (perc > 1.0)
- perc = 1.0;
+
+ if (bytes_total) {
+ perc = (double) bytes_done / (double) bytes_total;
+ if (perc > 1.0)
+ perc = 1.0;
+ } else
+ perc = 0.0;
if (td->o.time_based) {
- perc_t = (double) elapsed / (double) timeout;
- if (perc_t < perc)
- perc = perc_t;
+ if (timeout) {
+ perc_t = (double) elapsed / (double) timeout;
+ if (perc_t < perc)
+ perc = perc_t;
+ } else {
+ /*
+ * Will never hit, we can't have time_based
+ * without a timeout set.
+ */
+ perc = 0.0;
+ }
}
eta_sec = (unsigned long) (elapsed * (1.0 / perc)) - elapsed;
void print_status_init(int thr_number)
{
- run_str[thr_number] = 'P';
+ __run_str[thr_number] = 'P';
+ update_condensed_str(__run_str, run_str);
}