~ubuntu-branches/ubuntu/wily/qemu-kvm-spice/wily

« back to all changes in this revision

Viewing changes to qemu-progress.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-10-19 10:44:56 UTC
  • Revision ID: james.westby@ubuntu.com-20111019104456-xgvskumk3sxi97f4
Tags: upstream-0.15.0+noroms
ImportĀ upstreamĀ versionĀ 0.15.0+noroms

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}