root / qemu-progress.c @ e3e87df4
History | View | Annotate | Download (4 kB)
1 | 6b837bc4 | Jes Sorensen | /*
|
---|---|---|---|
2 | 6b837bc4 | Jes Sorensen | * QEMU progress printing utility functions
|
3 | 6b837bc4 | Jes Sorensen | *
|
4 | 6b837bc4 | Jes Sorensen | * Copyright (C) 2011 Jes Sorensen <Jes.Sorensen@redhat.com>
|
5 | 6b837bc4 | Jes Sorensen | *
|
6 | 6b837bc4 | Jes Sorensen | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 | 6b837bc4 | Jes Sorensen | * of this software and associated documentation files (the "Software"), to deal
|
8 | 6b837bc4 | Jes Sorensen | * in the Software without restriction, including without limitation the rights
|
9 | 6b837bc4 | Jes Sorensen | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10 | 6b837bc4 | Jes Sorensen | * copies of the Software, and to permit persons to whom the Software is
|
11 | 6b837bc4 | Jes Sorensen | * furnished to do so, subject to the following conditions:
|
12 | 6b837bc4 | Jes Sorensen | *
|
13 | 6b837bc4 | Jes Sorensen | * The above copyright notice and this permission notice shall be included in
|
14 | 6b837bc4 | Jes Sorensen | * all copies or substantial portions of the Software.
|
15 | 6b837bc4 | Jes Sorensen | *
|
16 | 6b837bc4 | Jes Sorensen | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 | 6b837bc4 | Jes Sorensen | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18 | 6b837bc4 | Jes Sorensen | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
19 | 6b837bc4 | Jes Sorensen | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20 | 6b837bc4 | Jes Sorensen | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 | 6b837bc4 | Jes Sorensen | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 | 6b837bc4 | Jes Sorensen | * THE SOFTWARE.
|
23 | 6b837bc4 | Jes Sorensen | */
|
24 | 6b837bc4 | Jes Sorensen | |
25 | 6b837bc4 | Jes Sorensen | #include "qemu-common.h" |
26 | 6b837bc4 | Jes Sorensen | #include "osdep.h" |
27 | 6b837bc4 | Jes Sorensen | #include "sysemu.h" |
28 | 6b837bc4 | Jes Sorensen | #include <stdio.h> |
29 | 6b837bc4 | Jes Sorensen | |
30 | 6b837bc4 | Jes Sorensen | struct progress_state {
|
31 | 6b837bc4 | Jes Sorensen | float current;
|
32 | 6b837bc4 | Jes Sorensen | float last_print;
|
33 | 6b837bc4 | Jes Sorensen | float min_skip;
|
34 | a55c73ba | Jes Sorensen | void (*print)(void); |
35 | a55c73ba | Jes Sorensen | void (*end)(void); |
36 | 6b837bc4 | Jes Sorensen | }; |
37 | 6b837bc4 | Jes Sorensen | |
38 | 6b837bc4 | Jes Sorensen | static struct progress_state state; |
39 | 2ab3cb8c | Jes Sorensen | static volatile sig_atomic_t print_pending; |
40 | 6b837bc4 | Jes Sorensen | |
41 | 6b837bc4 | Jes Sorensen | /*
|
42 | 6b837bc4 | Jes Sorensen | * Simple progress print function.
|
43 | 6b837bc4 | Jes Sorensen | * @percent relative percent of current operation
|
44 | 6b837bc4 | Jes Sorensen | * @max percent of total operation
|
45 | 6b837bc4 | Jes Sorensen | */
|
46 | 6b837bc4 | Jes Sorensen | static void progress_simple_print(void) |
47 | 6b837bc4 | Jes Sorensen | { |
48 | df6e008a | Jes Sorensen | printf(" (%3.2f/100%%)\r", state.current);
|
49 | df6e008a | Jes Sorensen | fflush(stdout); |
50 | 6b837bc4 | Jes Sorensen | } |
51 | 6b837bc4 | Jes Sorensen | |
52 | 6b837bc4 | Jes Sorensen | static void progress_simple_end(void) |
53 | 6b837bc4 | Jes Sorensen | { |
54 | a55c73ba | Jes Sorensen | printf("\n");
|
55 | a55c73ba | Jes Sorensen | } |
56 | a55c73ba | Jes Sorensen | |
57 | a55c73ba | Jes Sorensen | static void progress_simple_init(void) |
58 | a55c73ba | Jes Sorensen | { |
59 | a55c73ba | Jes Sorensen | state.print = progress_simple_print; |
60 | a55c73ba | Jes Sorensen | state.end = progress_simple_end; |
61 | a55c73ba | Jes Sorensen | } |
62 | a55c73ba | Jes Sorensen | |
63 | a55c73ba | Jes Sorensen | #ifdef CONFIG_POSIX
|
64 | a55c73ba | Jes Sorensen | static void sigusr_print(int signal) |
65 | a55c73ba | Jes Sorensen | { |
66 | 2ab3cb8c | Jes Sorensen | print_pending = 1;
|
67 | a55c73ba | Jes Sorensen | } |
68 | a55c73ba | Jes Sorensen | #endif
|
69 | a55c73ba | Jes Sorensen | |
70 | a55c73ba | Jes Sorensen | static void progress_dummy_print(void) |
71 | a55c73ba | Jes Sorensen | { |
72 | 2ab3cb8c | Jes Sorensen | if (print_pending) {
|
73 | 2ab3cb8c | Jes Sorensen | fprintf(stderr, " (%3.2f/100%%)\n", state.current);
|
74 | 2ab3cb8c | Jes Sorensen | print_pending = 0;
|
75 | 2ab3cb8c | Jes Sorensen | } |
76 | a55c73ba | Jes Sorensen | } |
77 | a55c73ba | Jes Sorensen | |
78 | a55c73ba | Jes Sorensen | static void progress_dummy_end(void) |
79 | a55c73ba | Jes Sorensen | { |
80 | a55c73ba | Jes Sorensen | } |
81 | a55c73ba | Jes Sorensen | |
82 | a55c73ba | Jes Sorensen | static void progress_dummy_init(void) |
83 | a55c73ba | Jes Sorensen | { |
84 | a55c73ba | Jes Sorensen | #ifdef CONFIG_POSIX
|
85 | a55c73ba | Jes Sorensen | struct sigaction action;
|
86 | a55c73ba | Jes Sorensen | |
87 | a55c73ba | Jes Sorensen | memset(&action, 0, sizeof(action)); |
88 | a55c73ba | Jes Sorensen | sigfillset(&action.sa_mask); |
89 | a55c73ba | Jes Sorensen | action.sa_handler = sigusr_print; |
90 | a55c73ba | Jes Sorensen | action.sa_flags = 0;
|
91 | a55c73ba | Jes Sorensen | sigaction(SIGUSR1, &action, NULL);
|
92 | a55c73ba | Jes Sorensen | #endif
|
93 | a55c73ba | Jes Sorensen | |
94 | a55c73ba | Jes Sorensen | state.print = progress_dummy_print; |
95 | a55c73ba | Jes Sorensen | state.end = progress_dummy_end; |
96 | 6b837bc4 | Jes Sorensen | } |
97 | 6b837bc4 | Jes Sorensen | |
98 | 3bfe4dbf | Jes Sorensen | /*
|
99 | 3bfe4dbf | Jes Sorensen | * Initialize progress reporting.
|
100 | 3bfe4dbf | Jes Sorensen | * If @enabled is false, actual reporting is suppressed. The user can
|
101 | 3bfe4dbf | Jes Sorensen | * still trigger a report by sending a SIGUSR1.
|
102 | 3bfe4dbf | Jes Sorensen | * Reports are also suppressed unless we've had at least @min_skip
|
103 | 3bfe4dbf | Jes Sorensen | * percent progress since the last report.
|
104 | 3bfe4dbf | Jes Sorensen | */
|
105 | 6b837bc4 | Jes Sorensen | void qemu_progress_init(int enabled, float min_skip) |
106 | 6b837bc4 | Jes Sorensen | { |
107 | 6b837bc4 | Jes Sorensen | state.min_skip = min_skip; |
108 | a55c73ba | Jes Sorensen | if (enabled) {
|
109 | a55c73ba | Jes Sorensen | progress_simple_init(); |
110 | a55c73ba | Jes Sorensen | } else {
|
111 | a55c73ba | Jes Sorensen | progress_dummy_init(); |
112 | a55c73ba | Jes Sorensen | } |
113 | 6b837bc4 | Jes Sorensen | } |
114 | 6b837bc4 | Jes Sorensen | |
115 | 6b837bc4 | Jes Sorensen | void qemu_progress_end(void) |
116 | 6b837bc4 | Jes Sorensen | { |
117 | a55c73ba | Jes Sorensen | state.end(); |
118 | 6b837bc4 | Jes Sorensen | } |
119 | 6b837bc4 | Jes Sorensen | |
120 | 3bfe4dbf | Jes Sorensen | /*
|
121 | 3bfe4dbf | Jes Sorensen | * Report progress.
|
122 | 3bfe4dbf | Jes Sorensen | * @delta is how much progress we made.
|
123 | 3bfe4dbf | Jes Sorensen | * If @max is zero, @delta is an absolut value of the total job done.
|
124 | 3bfe4dbf | Jes Sorensen | * Else, @delta is a progress delta since the last call, as a fraction
|
125 | 3bfe4dbf | Jes Sorensen | * of @max. I.e. the delta is @delta * @max / 100. This allows
|
126 | 3bfe4dbf | Jes Sorensen | * relative accounting of functions which may be a different fraction of
|
127 | 3bfe4dbf | Jes Sorensen | * the full job, depending on the context they are called in. I.e.
|
128 | 3bfe4dbf | Jes Sorensen | * a function might be considered 40% of the full job if used from
|
129 | 3bfe4dbf | Jes Sorensen | * bdrv_img_create() but only 20% if called from img_convert().
|
130 | 3bfe4dbf | Jes Sorensen | */
|
131 | 3bfe4dbf | Jes Sorensen | void qemu_progress_print(float delta, int max) |
132 | 6b837bc4 | Jes Sorensen | { |
133 | 6b837bc4 | Jes Sorensen | float current;
|
134 | 6b837bc4 | Jes Sorensen | |
135 | 6b837bc4 | Jes Sorensen | if (max == 0) { |
136 | 3bfe4dbf | Jes Sorensen | current = delta; |
137 | 6b837bc4 | Jes Sorensen | } else {
|
138 | 3bfe4dbf | Jes Sorensen | current = state.current + delta / 100 * max;
|
139 | 6b837bc4 | Jes Sorensen | } |
140 | 6b837bc4 | Jes Sorensen | if (current > 100) { |
141 | 6b837bc4 | Jes Sorensen | current = 100;
|
142 | 6b837bc4 | Jes Sorensen | } |
143 | 6b837bc4 | Jes Sorensen | state.current = current; |
144 | 6b837bc4 | Jes Sorensen | |
145 | 6b837bc4 | Jes Sorensen | if (current > (state.last_print + state.min_skip) ||
|
146 | 6b837bc4 | Jes Sorensen | (current == 100) || (current == 0)) { |
147 | 6b837bc4 | Jes Sorensen | state.last_print = state.current; |
148 | a55c73ba | Jes Sorensen | state.print(); |
149 | 6b837bc4 | Jes Sorensen | } |
150 | 6b837bc4 | Jes Sorensen | } |