Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 : : /*
3 : : * The most important part of pflash, the progress bars
4 : : *
5 : : * Copyright 2014-2017 IBM Corp.
6 : : */
7 : :
8 : : #include <inttypes.h>
9 : : #include <limits.h>
10 : : #include <stdint.h>
11 : : #include <stdio.h>
12 : : #include <stdlib.h>
13 : : #include <string.h>
14 : : #include <time.h>
15 : :
16 : : #include "progress.h"
17 : :
18 : : static uint64_t progress_max;
19 : : static uint64_t progress_pcent;
20 : : static uint64_t progress_n_upd;
21 : : static time_t progress_prevsec;
22 : : static struct timespec progress_start;
23 : :
24 : : #define PROGRESS_CHARS 50
25 : :
26 : 6 : void progress_init(uint64_t count)
27 : : {
28 : 6 : unsigned int i;
29 : :
30 : 6 : progress_max = count;
31 : 6 : progress_pcent = 0;
32 : 6 : progress_n_upd = ULONG_MAX;
33 : 6 : progress_prevsec = ULONG_MAX;
34 : :
35 : 6 : printf("\r[");
36 : 312 : for (i = 0; i < PROGRESS_CHARS; i++)
37 : 300 : printf(" ");
38 : 6 : printf("] 0%%");
39 : 6 : fflush(stdout);
40 : 6 : clock_gettime(CLOCK_MONOTONIC, &progress_start);}
41 : :
42 : 3333 : void progress_tick(uint64_t cur)
43 : : {
44 : 3333 : unsigned int i, pos;
45 : 3333 : struct timespec now;
46 : 3333 : uint64_t pcent;
47 : 3333 : double sec;
48 : :
49 : 3333 : pcent = (cur * 100) / progress_max;
50 : 3333 : if (progress_pcent == pcent && cur < progress_n_upd &&
51 : : cur < progress_max)
52 : 2932 : return;
53 : 401 : progress_pcent = pcent;
54 : 401 : pos = (pcent * PROGRESS_CHARS) / 101;
55 : 401 : clock_gettime(CLOCK_MONOTONIC, &now);
56 : :
57 : 401 : printf("\r[");
58 : 11052 : for (i = 0; i <= pos; i++)
59 : 10250 : printf("=");
60 : 10201 : for (; i < PROGRESS_CHARS; i++)
61 : 9800 : printf(" ");
62 : 401 : printf("] %" PRIu64 "%%", pcent);
63 : :
64 : 401 : sec = difftime(now.tv_sec, progress_start.tv_sec);
65 : 401 : if (sec >= 5 && pcent > 0) {
66 : 0 : uint64_t persec = cur / sec;
67 : 0 : uint64_t rem_sec;
68 : :
69 : 0 : if (!persec)
70 : : persec = 1;
71 : 0 : progress_n_upd = cur + persec;
72 : 0 : rem_sec = ((sec * 100) + (pcent / 2)) / pcent - sec;
73 : 0 : if (rem_sec > progress_prevsec)
74 : : rem_sec = progress_prevsec;
75 : 0 : progress_prevsec = rem_sec;
76 : 0 : if (rem_sec < 60)
77 : 0 : printf(" ETA:%" PRIu64 "s ", rem_sec);
78 : : else {
79 : 0 : printf(" ETA:%" PRIu64 ":%02" PRIu64 ":%02" PRIu64 " ",
80 : : rem_sec / 3600,
81 : 0 : (rem_sec / 60) % 60,
82 : : rem_sec % 60);
83 : : }
84 : : }
85 : :
86 : 401 : fflush(stdout);
87 : : }
88 : :
89 : 6 : void progress_end(void)
90 : : {
91 : 6 : printf("\n");
92 : 6 : }
|