MINOR: activity: report totals and average separately

Some fields need to be averaged instead of summed (e.g. avg_poll_us)
when reported on the CLI. Let's have a distinct macro for this.
diff --git a/src/cli.c b/src/cli.c
index 159c27d..41f403b 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -1068,8 +1068,8 @@
 
 	chunk_reset(&trash);
 
-#undef SHOW
-#define SHOW(t, x)							\
+#undef SHOW_TOT
+#define SHOW_TOT(t, x)							\
 	do {								\
 		unsigned int _v[MAX_THREADS];				\
 		unsigned int _tot;					\
@@ -1086,39 +1086,57 @@
 		chunk_appendf(&trash, " ]\n");				\
 	} while (0)
 
+#undef SHOW_AVG
+#define SHOW_AVG(t, x)							\
+	do {								\
+		unsigned int _v[MAX_THREADS];				\
+		unsigned int _tot;					\
+		const unsigned int _nbt = global.nbthread;		\
+		for (_tot = t = 0; t < _nbt; t++)			\
+			_tot += _v[t] = (x);				\
+		if (_nbt == 1) {					\
+			chunk_appendf(&trash, " %u\n", _tot);		\
+			break;						\
+		}							\
+		chunk_appendf(&trash, " %u [", (_tot + _nbt/2) / _nbt); \
+		for (t = 0; t < _nbt; t++)				\
+			chunk_appendf(&trash, " %u", _v[t]);		\
+		chunk_appendf(&trash, " ]\n");				\
+	} while (0)
+
 	chunk_appendf(&trash, "thread_id: %u (%u..%u)\n", tid + 1, 1, global.nbthread);
 	chunk_appendf(&trash, "date_now: %lu.%06lu\n", (long)now.tv_sec, (long)now.tv_usec);
-	chunk_appendf(&trash, "loops:");        SHOW(thr, activity[thr].loops);
-	chunk_appendf(&trash, "wake_cache:");   SHOW(thr, activity[thr].wake_cache);
-	chunk_appendf(&trash, "wake_tasks:");   SHOW(thr, activity[thr].wake_tasks);
-	chunk_appendf(&trash, "wake_signal:");  SHOW(thr, activity[thr].wake_signal);
-	chunk_appendf(&trash, "poll_exp:");     SHOW(thr, activity[thr].poll_exp);
-	chunk_appendf(&trash, "poll_drop:");    SHOW(thr, activity[thr].poll_drop);
-	chunk_appendf(&trash, "poll_dead:");    SHOW(thr, activity[thr].poll_dead);
-	chunk_appendf(&trash, "poll_skip:");    SHOW(thr, activity[thr].poll_skip);
-	chunk_appendf(&trash, "fd_lock:");      SHOW(thr, activity[thr].fd_lock);
-	chunk_appendf(&trash, "conn_dead:");    SHOW(thr, activity[thr].conn_dead);
-	chunk_appendf(&trash, "stream:");       SHOW(thr, activity[thr].stream);
-	chunk_appendf(&trash, "empty_rq:");     SHOW(thr, activity[thr].empty_rq);
-	chunk_appendf(&trash, "long_rq:");      SHOW(thr, activity[thr].long_rq);
-	chunk_appendf(&trash, "ctxsw:");        SHOW(thr, activity[thr].ctxsw);
-	chunk_appendf(&trash, "tasksw:");       SHOW(thr, activity[thr].tasksw);
-	chunk_appendf(&trash, "cpust_ms_tot:"); SHOW(thr, activity[thr].cpust_total / 2);
-	chunk_appendf(&trash, "cpust_ms_1s:");  SHOW(thr, read_freq_ctr(&activity[thr].cpust_1s) / 2);
-	chunk_appendf(&trash, "cpust_ms_15s:"); SHOW(thr, read_freq_ctr_period(&activity[thr].cpust_15s, 15000) / 2);
-	chunk_appendf(&trash, "avg_loop_us:");  SHOW(thr, swrate_avg(activity[thr].avg_loop_us, TIME_STATS_SAMPLES));
-	chunk_appendf(&trash, "accepted:");     SHOW(thr, activity[thr].accepted);
-	chunk_appendf(&trash, "accq_pushed:");  SHOW(thr, activity[thr].accq_pushed);
-	chunk_appendf(&trash, "accq_full:");    SHOW(thr, activity[thr].accq_full);
+	chunk_appendf(&trash, "loops:");        SHOW_TOT(thr, activity[thr].loops);
+	chunk_appendf(&trash, "wake_cache:");   SHOW_TOT(thr, activity[thr].wake_cache);
+	chunk_appendf(&trash, "wake_tasks:");   SHOW_TOT(thr, activity[thr].wake_tasks);
+	chunk_appendf(&trash, "wake_signal:");  SHOW_TOT(thr, activity[thr].wake_signal);
+	chunk_appendf(&trash, "poll_exp:");     SHOW_TOT(thr, activity[thr].poll_exp);
+	chunk_appendf(&trash, "poll_drop:");    SHOW_TOT(thr, activity[thr].poll_drop);
+	chunk_appendf(&trash, "poll_dead:");    SHOW_TOT(thr, activity[thr].poll_dead);
+	chunk_appendf(&trash, "poll_skip:");    SHOW_TOT(thr, activity[thr].poll_skip);
+	chunk_appendf(&trash, "fd_lock:");      SHOW_TOT(thr, activity[thr].fd_lock);
+	chunk_appendf(&trash, "conn_dead:");    SHOW_TOT(thr, activity[thr].conn_dead);
+	chunk_appendf(&trash, "stream:");       SHOW_TOT(thr, activity[thr].stream);
+	chunk_appendf(&trash, "empty_rq:");     SHOW_TOT(thr, activity[thr].empty_rq);
+	chunk_appendf(&trash, "long_rq:");      SHOW_TOT(thr, activity[thr].long_rq);
+	chunk_appendf(&trash, "ctxsw:");        SHOW_TOT(thr, activity[thr].ctxsw);
+	chunk_appendf(&trash, "tasksw:");       SHOW_TOT(thr, activity[thr].tasksw);
+	chunk_appendf(&trash, "cpust_ms_tot:"); SHOW_TOT(thr, activity[thr].cpust_total / 2);
+	chunk_appendf(&trash, "cpust_ms_1s:");  SHOW_TOT(thr, read_freq_ctr(&activity[thr].cpust_1s) / 2);
+	chunk_appendf(&trash, "cpust_ms_15s:"); SHOW_TOT(thr, read_freq_ctr_period(&activity[thr].cpust_15s, 15000) / 2);
+	chunk_appendf(&trash, "avg_loop_us:");  SHOW_AVG(thr, swrate_avg(activity[thr].avg_loop_us, TIME_STATS_SAMPLES));
+	chunk_appendf(&trash, "accepted:");     SHOW_TOT(thr, activity[thr].accepted);
+	chunk_appendf(&trash, "accq_pushed:");  SHOW_TOT(thr, activity[thr].accq_pushed);
+	chunk_appendf(&trash, "accq_full:");    SHOW_TOT(thr, activity[thr].accq_full);
 #ifdef USE_THREAD
-	chunk_appendf(&trash, "accq_ring:");    SHOW(thr, (accept_queue_rings[thr].tail - accept_queue_rings[thr].head + ACCEPT_QUEUE_SIZE) % ACCEPT_QUEUE_SIZE);
+	chunk_appendf(&trash, "accq_ring:");    SHOW_TOT(thr, (accept_queue_rings[thr].tail - accept_queue_rings[thr].head + ACCEPT_QUEUE_SIZE) % ACCEPT_QUEUE_SIZE);
 #endif
 
 #if defined(DEBUG_DEV)
 	/* keep these ones at the end */
-	chunk_appendf(&trash, "ctr0:");         SHOW(thr, activity[thr].ctr0);
-	chunk_appendf(&trash, "ctr1:");         SHOW(thr, activity[thr].ctr1);
-	chunk_appendf(&trash, "ctr2:");         SHOW(thr, activity[thr].ctr2);
+	chunk_appendf(&trash, "ctr0:");         SHOW_TOT(thr, activity[thr].ctr0);
+	chunk_appendf(&trash, "ctr1:");         SHOW_TOT(thr, activity[thr].ctr1);
+	chunk_appendf(&trash, "ctr2:");         SHOW_TOT(thr, activity[thr].ctr2);
 #endif
 
 	if (ci_putchk(si_ic(si), &trash) == -1) {
@@ -1127,7 +1145,8 @@
 		si_rx_room_blk(si);
 	}
 
-#undef SHOW
+#undef SHOW_AVG
+#undef SHOW_TOT
 	/* dump complete */
 	return 1;
 }