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 |
} |