[PATCH] Split status/eta code out of fio.c

All in the name of making the code base easier to go through.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
diff --git a/fio.c b/fio.c
index 1fb35fb..a146f03 100644
--- a/fio.c
+++ b/fio.c
@@ -41,33 +41,12 @@
 
 int groupid = 0;
 int thread_number = 0;
-static char run_str[MAX_JOBS + 1];
 int shm_id = 0;
-static struct timeval genesis;
 int temp_stall_ts;
 char *fio_inst_prefix = _INST_PREFIX;
 
-static void print_thread_status(void);
-
 extern unsigned long long mlock_size;
 
-/*
- * Thread life cycle. Once a thread has a runstate beyond TD_INITIALIZED, it
- * will never back again. It may cycle between running/verififying/fsyncing.
- * Once the thread reaches TD_EXITED, it is just waiting for the core to
- * reap it.
- */
-enum {
-	TD_NOT_CREATED = 0,
-	TD_CREATED,
-	TD_INITIALIZED,
-	TD_RUNNING,
-	TD_VERIFYING,
-	TD_FSYNCING,
-	TD_EXITED,
-	TD_REAPED,
-};
-
 #define should_fsync(td)	((td_write(td) || td_rw(td)) && (!(td)->odirect || (td)->override_sync))
 
 static volatile int startup_sem;
@@ -1257,221 +1236,6 @@
 }
 
 /*
- * 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];
-
-	switch (td->runstate) {
-		case TD_REAPED:
-			c = '_';
-			break;
-		case TD_EXITED:
-			c = 'E';
-			break;
-		case TD_RUNNING:
-			if (td_rw(td)) {
-				if (td->sequential)
-					c = 'M';
-				else
-					c = 'm';
-			} else if (td_read(td)) {
-				if (td->sequential)
-					c = 'R';
-				else
-					c = 'r';
-			} else {
-				if (td->sequential)
-					c = 'W';
-				else
-					c = 'w';
-			}
-			break;
-		case TD_VERIFYING:
-			c = 'V';
-			break;
-		case TD_FSYNCING:
-			c = 'F';
-			break;
-		case TD_CREATED:
-			c = 'C';
-			break;
-		case TD_INITIALIZED:
-			c = 'I';
-			break;
-		case TD_NOT_CREATED:
-			c = 'P';
-			break;
-		default:
-			log_err("state %d\n", td->runstate);
-	}
-
-	run_str[td->thread_number - 1] = c;
-}
-
-/*
- * Convert seconds to a printable string.
- */
-static void eta_to_str(char *str, int eta_sec)
-{
-	unsigned int d, h, m, s;
-	static int always_d, always_h;
-
-	d = h = m = s = 0;
-
-	s = eta_sec % 60;
-	eta_sec /= 60;
-	m = eta_sec % 60;
-	eta_sec /= 60;
-	h = eta_sec % 24;
-	eta_sec /= 24;
-	d = eta_sec;
-
-	if (d || always_d) {
-		always_d = 1;
-		str += sprintf(str, "%02dd:", d);
-	}
-	if (h || always_h) {
-		always_h = 1;
-		str += sprintf(str, "%02dh:", h);
-	}
-
-	str += sprintf(str, "%02dm:", m);
-	str += sprintf(str, "%02ds", s);
-}
-
-/*
- * Best effort calculation of the estimated pending runtime of a job.
- */
-static int thread_eta(struct thread_data *td, unsigned long elapsed)
-{
-	unsigned long long bytes_total, bytes_done;
-	unsigned int eta_sec = 0;
-
-	bytes_total = td->total_io_size;
-
-	if (td->zone_size && td->zone_skip)
-		bytes_total /= (td->zone_skip / td->zone_size);
-
-	if (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING) {
-		double perc;
-
-		bytes_done = td->io_bytes[DDIR_READ] + td->io_bytes[DDIR_WRITE];
-		perc = (double) bytes_done / (double) bytes_total;
-		if (perc > 1.0)
-			perc = 1.0;
-
-		eta_sec = (elapsed * (1.0 / perc)) - elapsed;
-
-		if (td->timeout && eta_sec > (td->timeout - elapsed))
-			eta_sec = td->timeout - elapsed;
-	} else if (td->runstate == TD_NOT_CREATED || td->runstate == TD_CREATED
-			|| td->runstate == TD_INITIALIZED) {
-		int t_eta = 0, r_eta = 0;
-
-		/*
-		 * We can only guess - assume it'll run the full timeout
-		 * if given, otherwise assume it'll run at the specified rate.
-		 */
-		if (td->timeout)
-			t_eta = td->timeout + td->start_delay - elapsed;
-		if (td->rate) {
-			r_eta = (bytes_total / 1024) / td->rate;
-			r_eta += td->start_delay - elapsed;
-		}
-
-		if (r_eta && t_eta)
-			eta_sec = min(r_eta, t_eta);
-		else if (r_eta)
-			eta_sec = r_eta;
-		else if (t_eta)
-			eta_sec = t_eta;
-		else
-			eta_sec = 0;
-	} else {
-		/*
-		 * thread is already done or waiting for fsync
-		 */
-		eta_sec = 0;
-	}
-
-	return eta_sec;
-}
-
-/*
- * Print status of the jobs we know about. This includes rate estimates,
- * ETA, thread state, etc.
- */
-static void print_thread_status(void)
-{
-	unsigned long elapsed = time_since_now(&genesis);
-	int i, nr_running, nr_pending, t_rate, m_rate, *eta_secs, eta_sec;
-	char eta_str[32];
-	double perc = 0.0;
-
-	if (temp_stall_ts || terse_output)
-		return;
-
-	eta_secs = malloc(thread_number * sizeof(int));
-	memset(eta_secs, 0, thread_number * sizeof(int));
-
-	nr_pending = nr_running = t_rate = m_rate = 0;
-	for (i = 0; i < thread_number; i++) {
-		struct thread_data *td = &threads[i];
-
-		if (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING||
-		    td->runstate == TD_FSYNCING) {
-			nr_running++;
-			t_rate += td->rate;
-			m_rate += td->ratemin;
-		} else if (td->runstate < TD_RUNNING)
-			nr_pending++;
-
-		if (elapsed >= 3)
-			eta_secs[i] = thread_eta(td, elapsed);
-		else
-			eta_secs[i] = INT_MAX;
-
-		check_str_update(td);
-	}
-
-	if (exitall_on_terminate)
-		eta_sec = INT_MAX;
-	else
-		eta_sec = 0;
-
-	for (i = 0; i < thread_number; i++) {
-		if (exitall_on_terminate) {
-			if (eta_secs[i] < eta_sec)
-				eta_sec = eta_secs[i];
-		} else {
-			if (eta_secs[i] > eta_sec)
-				eta_sec = eta_secs[i];
-		}
-	}
-
-	if (eta_sec != INT_MAX && elapsed) {
-		perc = (double) elapsed / (double) (elapsed + eta_sec);
-		eta_to_str(eta_str, eta_sec);
-	}
-
-	if (!nr_running && !nr_pending)
-		return;
-
-	printf("Threads running: %d", nr_running);
-	if (m_rate || t_rate)
-		printf(", commitrate %d/%dKiB/sec", t_rate, m_rate);
-	if (eta_sec != INT_MAX && nr_running) {
-		perc *= 100.0;
-		printf(": [%s] [%3.2f%% done] [eta %s]", run_str, perc,eta_str);
-	}
-	printf("\r");
-	fflush(stdout);
-	free(eta_secs);
-}
-
-/*
  * Run over the job map and reap the threads that have exited, if any.
  */
 static void reap_threads(int *nr_running, int *t_rate, int *m_rate)
@@ -1579,7 +1343,7 @@
 	for (i = 0; i < thread_number; i++) {
 		td = &threads[i];
 
-		run_str[td->thread_number - 1] = 'P';
+		print_status_init(td->thread_number - 1);
 
 		init_disk_util(td);
 
@@ -1597,7 +1361,7 @@
 		}
 	}
 
-	gettimeofday(&genesis, NULL);
+	time_init();
 
 	while (todo) {
 		struct thread_data *map[MAX_JOBS];
@@ -1623,7 +1387,7 @@
 			}
 
 			if (td->start_delay) {
-				spent = mtime_since_now(&genesis);
+				spent = mtime_since_genesis();
 
 				if (td->start_delay * 1000 > spent)
 					continue;