Statistics
| Branch: | Revision:

root / qemu-progress.c @ 753d11f2

History | View | Annotate | Download (4 kB)

1
/*
2
 * QEMU progress printing utility functions
3
 *
4
 * Copyright (C) 2011 Jes Sorensen <Jes.Sorensen@redhat.com>
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

    
25
#include "qemu-common.h"
26
#include "osdep.h"
27
#include "sysemu.h"
28
#include <stdio.h>
29

    
30
struct progress_state {
31
    float current;
32
    float last_print;
33
    float min_skip;
34
    void (*print)(void);
35
    void (*end)(void);
36
};
37

    
38
static struct progress_state state;
39
static volatile sig_atomic_t print_pending;
40

    
41
/*
42
 * Simple progress print function.
43
 * @percent relative percent of current operation
44
 * @max percent of total operation
45
 */
46
static void progress_simple_print(void)
47
{
48
    printf("    (%3.2f/100%%)\r", state.current);
49
    fflush(stdout);
50
}
51

    
52
static void progress_simple_end(void)
53
{
54
    printf("\n");
55
}
56

    
57
static void progress_simple_init(void)
58
{
59
    state.print = progress_simple_print;
60
    state.end = progress_simple_end;
61
}
62

    
63
#ifdef CONFIG_POSIX
64
static void sigusr_print(int signal)
65
{
66
    print_pending = 1;
67
}
68
#endif
69

    
70
static void progress_dummy_print(void)
71
{
72
    if (print_pending) {
73
        fprintf(stderr, "    (%3.2f/100%%)\n", state.current);
74
        print_pending = 0;
75
    }
76
}
77

    
78
static void progress_dummy_end(void)
79
{
80
}
81

    
82
static void progress_dummy_init(void)
83
{
84
#ifdef CONFIG_POSIX
85
    struct sigaction action;
86

    
87
    memset(&action, 0, sizeof(action));
88
    sigfillset(&action.sa_mask);
89
    action.sa_handler = sigusr_print;
90
    action.sa_flags = 0;
91
    sigaction(SIGUSR1, &action, NULL);
92
#endif
93

    
94
    state.print = progress_dummy_print;
95
    state.end = progress_dummy_end;
96
}
97

    
98
/*
99
 * Initialize progress reporting.
100
 * If @enabled is false, actual reporting is suppressed.  The user can
101
 * still trigger a report by sending a SIGUSR1.
102
 * Reports are also suppressed unless we've had at least @min_skip
103
 * percent progress since the last report.
104
 */
105
void qemu_progress_init(int enabled, float min_skip)
106
{
107
    state.min_skip = min_skip;
108
    if (enabled) {
109
        progress_simple_init();
110
    } else {
111
        progress_dummy_init();
112
    }
113
}
114

    
115
void qemu_progress_end(void)
116
{
117
    state.end();
118
}
119

    
120
/*
121
 * Report progress.
122
 * @delta is how much progress we made.
123
 * If @max is zero, @delta is an absolut value of the total job done.
124
 * Else, @delta is a progress delta since the last call, as a fraction
125
 * of @max.  I.e. the delta is @delta * @max / 100. This allows
126
 * relative accounting of functions which may be a different fraction of
127
 * the full job, depending on the context they are called in. I.e.
128
 * a function might be considered 40% of the full job if used from
129
 * bdrv_img_create() but only 20% if called from img_convert().
130
 */
131
void qemu_progress_print(float delta, int max)
132
{
133
    float current;
134

    
135
    if (max == 0) {
136
        current = delta;
137
    } else {
138
        current = state.current + delta / 100 * max;
139
    }
140
    if (current > 100) {
141
        current = 100;
142
    }
143
    state.current = current;
144

    
145
    if (current > (state.last_print + state.min_skip) ||
146
        (current == 100) || (current == 0)) {
147
        state.last_print = state.current;
148
        state.print();
149
    }
150
}