Statistics
| Branch: | Revision:

root / drivers / tapdisk-stats.c @ abdb293f

History | View | Annotate | Download (3.7 kB)

1
/*
2
 * Copyright (c) 2010, Citrix Systems, Inc.
3
 *
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions are met:
8
 *     * Redistributions of source code must retain the above copyright
9
 *       notice, this list of conditions and the following disclaimer.
10
 *     * Redistributions in binary form must reproduce the above copyright
11
 *       notice, this list of conditions and the following disclaimer in the
12
 *       documentation and/or other materials provided with the distribution.
13
 *     * Neither the name of XenSource Inc. nor the names of its contributors
14
 *       may be used to endorse or promote products derived from this software
15
 *       without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 */
29

    
30
#ifdef HAVE_CONFIG_H
31
#include "config.h"
32
#endif
33

    
34
#include <stdio.h>
35
#include <stdarg.h>
36

    
37
#include "tapdisk.h"
38
#include "tapdisk-stats.h"
39

    
40
#define BUG_ON(_cond) if (_cond) { td_panic(); }
41

    
42
static void
43
__stats_vsprintf(td_stats_t *st,
44
                      const char *fmt, va_list ap)
45
{
46
        size_t size = st->buf + st->size - st->pos;
47
        st->pos += vsnprintf(st->pos, size, fmt, ap);
48
}
49

    
50
static void __printf(2, 3)
51
__stats_sprintf(td_stats_t *st,
52
                     const char *fmt, ...)
53
{
54
        va_list ap;
55

    
56
        va_start(ap, fmt);
57
        __stats_vsprintf(st, fmt, ap);
58
        va_end(ap);
59
}
60

    
61
static void
62
__stats_enter(td_stats_t *st)
63
{
64
        st->depth++;
65
        BUG_ON(st->depth > TD_STATS_MAX_DEPTH);
66
        st->n_elem[st->depth] = 0;
67
}
68

    
69
static void
70
__stats_leave(td_stats_t *st)
71
{
72
        st->depth--;
73
}
74

    
75
static void
76
__stats_next(td_stats_t *st)
77
{
78
        int n_elem;
79

    
80
        n_elem = st->n_elem[st->depth];
81
        if (n_elem > 0)
82
                __stats_sprintf(st, ", ");
83
        st->n_elem[st->depth]++;
84
}
85

    
86
static void
87
__tapdisk_stats_enter(td_stats_t *st, char t)
88
{
89
        __stats_sprintf(st, "%c ", t);
90
        __stats_enter(st);
91
}
92

    
93
void
94
tapdisk_stats_enter(td_stats_t *st, char t)
95
{
96
        __stats_next(st);
97
        __tapdisk_stats_enter(st, t);
98
}
99

    
100
void
101
tapdisk_stats_leave(td_stats_t *st, char t)
102
{
103
        __stats_leave(st);
104
        __stats_sprintf(st, " %c", t);
105
}
106

    
107
static void
108
tapdisk_stats_vval(td_stats_t *st, const char *conv, va_list ap)
109
{
110
        char t = conv[0], fmt[32];
111

    
112
        __stats_next(st);
113

    
114
        switch (t) {
115
        case 's':
116
                __stats_vsprintf(st, "\"%s\"", ap);
117
                break;
118

    
119
        default:
120
                sprintf(fmt, "%%%s", conv);
121
                __stats_vsprintf(st, fmt, ap);
122
                break;
123
        }
124
}
125

    
126
void
127
tapdisk_stats_val(td_stats_t *st, const char *conv, ...)
128
{
129
        va_list ap;
130

    
131
        va_start(ap, conv);
132
        tapdisk_stats_vval(st, conv, ap);
133
        va_end(ap);
134
}
135

    
136
void
137
tapdisk_stats_field(td_stats_t *st, const char *key, const char *conv, ...)
138
{
139
        va_list ap;
140
        int n_elem;
141
        char t;
142

    
143
        n_elem = st->n_elem[st->depth]++;
144
        if (n_elem > 0)
145
                __stats_sprintf(st, ", ");
146

    
147
        __stats_sprintf(st, "\"%s\": ", key);
148

    
149
        if (!conv) {
150
                __stats_sprintf(st, "null");
151
                return;
152
        }
153

    
154
        t = conv[0];
155
        switch (t) {
156
        case '[':
157
        case '{':
158
                __tapdisk_stats_enter(st, t);
159
                break;
160
        default:
161
                va_start(ap, conv);
162
                __stats_enter(st);
163
                tapdisk_stats_vval(st, conv, ap);
164
                __stats_leave(st);
165
                va_end(ap);
166
        }
167
}