[Pdbg] [PATCH] libpdbg: progress bars!

Joel Stanley joel at jms.id.au
Thu May 10 17:28:15 AEST 2018


 $ pdbg -p 0 getmem 0x8040278 100 > /tmp/log
 [==================================================] 100%

Signed-off-by: Joel Stanley <joel at jms.id.au>
---
 Makefile.am        |  1 +
 libpdbg/adu.c      |  6 +++
 libpdbg/progress.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++
 libpdbg/progress.h | 24 +++++++++++
 4 files changed, 130 insertions(+)
 create mode 100644 libpdbg/progress.c
 create mode 100644 libpdbg/progress.h

diff --git a/Makefile.am b/Makefile.am
index c6668d8e8038..ae8929bdd510 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -52,6 +52,7 @@ libpdbg_la_SOURCES = \
 	libpdbg/adu.c \
 	libpdbg/device.c \
 	libpdbg/target.c \
+	libpdbg/progress.c \
 	libpdbg/htm.c
 
 M4_V = $(M4_V_$(V))
diff --git a/libpdbg/adu.c b/libpdbg/adu.c
index 2a0b8d5f0020..a97d250a9245 100644
--- a/libpdbg/adu.c
+++ b/libpdbg/adu.c
@@ -20,6 +20,7 @@
 
 #include "operations.h"
 #include "bitutils.h"
+#include "progress.h"
 
 /* P8 ADU SCOM Register Definitions */
 #define P8_ALTD_CONTROL_REG	0x0
@@ -88,6 +89,8 @@ int adu_getmem(struct pdbg_target *adu_target, uint64_t start_addr, uint8_t *out
 	assert(!strcmp(adu_target->class, "adu"));
 	adu = target_to_adu(adu_target);
 
+	progress_init(size);
+
 	/* We read data in 8-byte aligned chunks */
 	for (addr = 8*(start_addr / 8); addr < start_addr + size; addr += 8) {
 		uint64_t data;
@@ -107,7 +110,10 @@ int adu_getmem(struct pdbg_target *adu_target, uint64_t start_addr, uint8_t *out
 			memcpy(output, &data, 8);
 			output += 8;
 		}
+		progress_tick(addr - start_addr);
 	}
+	progress_tick(size);
+	progress_end();
 
 	return rc;
 }
diff --git a/libpdbg/progress.c b/libpdbg/progress.c
new file mode 100644
index 000000000000..cf95015444e7
--- /dev/null
+++ b/libpdbg/progress.c
@@ -0,0 +1,99 @@
+/* Copyright 2018 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ */
+
+#include <inttypes.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "progress.h"
+
+static uint64_t progress_max;
+static uint64_t progress_pcent;
+static uint64_t progress_n_upd;
+static time_t progress_prevsec;
+static struct timespec progress_start;
+
+#define PROGRESS_CHARS	50
+
+void progress_init(uint64_t count)
+{
+	unsigned int i;
+
+	progress_max = count;
+	progress_pcent = 0;
+	progress_n_upd = ULONG_MAX;
+	progress_prevsec = ULONG_MAX;
+
+	fprintf(stderr, "\r[");
+	for (i = 0; i < PROGRESS_CHARS; i++)
+		fprintf(stderr, " ");
+	fprintf(stderr, "] 0%%");
+	fflush(stderr);
+	clock_gettime(CLOCK_MONOTONIC, &progress_start);}
+
+void progress_tick(uint64_t cur)
+{
+	unsigned int i, pos;
+	struct timespec now;
+	uint64_t pcent;
+	double sec;
+
+	pcent = (cur * 100) / progress_max;
+	if (progress_pcent == pcent && cur < progress_n_upd &&
+	    cur < progress_max)
+		return;
+	progress_pcent = pcent;
+	pos = (pcent * PROGRESS_CHARS) / 101;
+	clock_gettime(CLOCK_MONOTONIC, &now);
+
+	fprintf(stderr, "\r[");
+	for (i = 0; i <= pos; i++)
+		fprintf(stderr, "=");
+	for (; i < PROGRESS_CHARS; i++)
+		fprintf(stderr, " ");
+	fprintf(stderr, "] %" PRIu64 "%%", pcent);
+
+	sec = difftime(now.tv_sec, progress_start.tv_sec);
+	if (sec >= 5 && pcent > 0) {
+		uint64_t persec = cur / sec;
+		uint64_t rem_sec;
+
+		if (!persec)
+			persec = 1;
+		progress_n_upd = cur + persec;
+		rem_sec = ((sec * 100) + (pcent / 2)) / pcent - sec;
+		if (rem_sec > progress_prevsec)
+			rem_sec = progress_prevsec;
+		progress_prevsec = rem_sec;
+		if (rem_sec < 60)
+			fprintf(stderr, " ETA:%" PRIu64 "s     ", rem_sec);
+		else {
+			fprintf(stderr, " ETA:%" PRIu64 ":%02" PRIu64 ":%02" PRIu64 " ",
+				rem_sec / 3600,
+				(rem_sec / 60) % 60,
+				rem_sec % 60);
+		}
+	}
+
+	fflush(stderr);
+}
+
+void progress_end(void)
+{
+	fprintf(stderr, "\n");
+}
diff --git a/libpdbg/progress.h b/libpdbg/progress.h
new file mode 100644
index 000000000000..990f6d5bd8ac
--- /dev/null
+++ b/libpdbg/progress.h
@@ -0,0 +1,24 @@
+/* Copyright 2018 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ */
+
+#ifndef __PROGRESS_H
+#define __PROGRESS_H
+
+#include <inttypes.h>
+
+void progress_init(uint64_t count);
+void progress_tick(uint64_t cur);
+void progress_end(void);
+
+#endif /* __PROGRESS_H */
-- 
2.17.0



More information about the Pdbg mailing list