testprogs: Set functional domain level to 2003.
[Samba.git] / source3 / utils / status_profile.c
blobf0cf405e18515ee5fe66956d361946f6775adf70
1 /*
2 * Unix SMB/CIFS implementation.
3 * status reporting
4 * Copyright (C) Andrew Tridgell 1994-1998
5 * Copyright (C) James Peach 2005-2006
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "smbprofile.h"
23 #include "status_profile.h"
25 static void profile_separator(const char * title)
27 char line[79 + 1];
28 char * end;
30 snprintf(line, sizeof(line), "**** %s ", title);
32 for (end = line + strlen(line); end < &line[sizeof(line) -1]; ++end) {
33 *end = '*';
36 line[sizeof(line) - 1] = '\0';
37 d_printf("%s\n", line);
40 /*******************************************************************
41 dump the elements of the profile structure
42 ******************************************************************/
43 bool status_profile_dump(bool verbose)
45 if (!profile_setup(NULL, True)) {
46 fprintf(stderr,"Failed to initialise profile memory\n");
47 return False;
50 #define __PRINT_FIELD_LINE(name, _stats, field) do { \
51 d_printf("%-59s%20ju\n", \
52 name "_" #field ":", \
53 (uintmax_t)profile_p->_stats.field); \
54 } while(0);
55 #define SMBPROFILE_STATS_START
56 #define SMBPROFILE_STATS_SECTION_START(name) profile_separator(#name);
57 #define SMBPROFILE_STATS_COUNT(name) do { \
58 __PRINT_FIELD_LINE(#name, name##_stats, count); \
59 } while(0);
60 #define SMBPROFILE_STATS_TIME(name) do { \
61 __PRINT_FIELD_LINE(#name, name##_stats, time); \
62 } while(0);
63 #define SMBPROFILE_STATS_BASIC(name) do { \
64 __PRINT_FIELD_LINE(#name, name##_stats, count); \
65 __PRINT_FIELD_LINE(#name, name##_stats, time); \
66 } while(0);
67 #define SMBPROFILE_STATS_BYTES(name) do { \
68 __PRINT_FIELD_LINE(#name, name##_stats, count); \
69 __PRINT_FIELD_LINE(#name, name##_stats, time); \
70 __PRINT_FIELD_LINE(#name, name##_stats, idle); \
71 __PRINT_FIELD_LINE(#name, name##_stats, bytes); \
72 } while(0);
73 #define SMBPROFILE_STATS_IOBYTES(name) do { \
74 __PRINT_FIELD_LINE(#name, name##_stats, count); \
75 __PRINT_FIELD_LINE(#name, name##_stats, time); \
76 __PRINT_FIELD_LINE(#name, name##_stats, idle); \
77 __PRINT_FIELD_LINE(#name, name##_stats, inbytes); \
78 __PRINT_FIELD_LINE(#name, name##_stats, outbytes); \
79 } while(0);
80 #define SMBPROFILE_STATS_SECTION_END
81 #define SMBPROFILE_STATS_END
82 SMBPROFILE_STATS_ALL_SECTIONS
83 #undef __PRINT_FIELD_LINE
84 #undef SMBPROFILE_STATS_START
85 #undef SMBPROFILE_STATS_SECTION_START
86 #undef SMBPROFILE_STATS_COUNT
87 #undef SMBPROFILE_STATS_TIME
88 #undef SMBPROFILE_STATS_BASIC
89 #undef SMBPROFILE_STATS_BYTES
90 #undef SMBPROFILE_STATS_IOBYTES
91 #undef SMBPROFILE_STATS_SECTION_END
92 #undef SMBPROFILE_STATS_END
94 return True;
97 /* Convert microseconds to milliseconds. */
98 #define usec_to_msec(s) ((s) / 1000)
99 /* Convert microseconds to seconds. */
100 #define usec_to_sec(s) ((s) / 1000000)
101 /* One second in microseconds. */
102 #define one_second_usec (1000000)
104 #define sample_interval_usec one_second_usec
106 #define percent_time(used, period) ((double)(used) / (double)(period) * 100.0 )
108 static uint64_t print_count_count_samples(
109 char *buf, const size_t buflen,
110 const char *name,
111 const struct smbprofile_stats_count * const current,
112 const struct smbprofile_stats_count * const last,
113 uint64_t delta_usec)
115 uint64_t step = current->count - last->count;
116 uint64_t count = 0;
118 if (step != 0) {
119 uint64_t delta_sec = usec_to_sec(delta_usec);
121 count++;
123 if (buf[0] == '\0') {
124 snprintf(buf, buflen,
125 "%s %ju/sec",
126 name, (uintmax_t)(step / delta_sec));
127 } else {
128 printf("%-40s %s %ju/sec\n",
129 buf, name, (uintmax_t)(step / delta_sec));
130 buf[0] = '\0';
134 return count;
137 static uint64_t print_basic_count_samples(
138 char *buf, const size_t buflen,
139 const char *name,
140 const struct smbprofile_stats_basic * const current,
141 const struct smbprofile_stats_basic * const last,
142 uint64_t delta_usec)
144 uint64_t step = current->count - last->count;
145 uint64_t spent = current->time - last->time;
146 uint64_t count = 0;
148 if (step != 0) {
149 uint64_t delta_sec = usec_to_sec(delta_usec);
151 count++;
153 if (buf[0] == '\0') {
154 snprintf(buf, buflen,
155 "%s %ju/sec (%.2f%%)",
156 name, (uintmax_t)(step / delta_sec),
157 percent_time(spent, delta_usec));
158 } else {
159 printf("%-40s %s %ju/sec (%.2f%%)\n",
160 buf, name, (uintmax_t)(step / delta_sec),
161 percent_time(spent, delta_usec));
162 buf[0] = '\0';
166 return count;
169 static uint64_t print_bytes_count_samples(
170 char *buf, const size_t buflen,
171 const char *name,
172 const struct smbprofile_stats_bytes * const current,
173 const struct smbprofile_stats_bytes * const last,
174 uint64_t delta_usec)
176 uint64_t step = current->count - last->count;
177 uint64_t spent = current->time - last->time;
178 uint64_t count = 0;
180 if (step != 0) {
181 uint64_t delta_sec = usec_to_sec(delta_usec);
183 count++;
185 if (buf[0] == '\0') {
186 snprintf(buf, buflen,
187 "%s %ju/sec (%.2f%%)",
188 name, (uintmax_t)(step / delta_sec),
189 percent_time(spent, delta_usec));
190 } else {
191 printf("%-40s %s %ju/sec (%.2f%%)\n",
192 buf, name, (uintmax_t)(step / delta_sec),
193 percent_time(spent, delta_usec));
194 buf[0] = '\0';
198 return count;
201 static uint64_t print_iobytes_count_samples(
202 char *buf, const size_t buflen,
203 const char *name,
204 const struct smbprofile_stats_iobytes * const current,
205 const struct smbprofile_stats_iobytes * const last,
206 uint64_t delta_usec)
208 uint64_t step = current->count - last->count;
209 uint64_t spent = current->time - last->time;
210 uint64_t count = 0;
212 if (step != 0) {
213 uint64_t delta_sec = usec_to_sec(delta_usec);
215 count++;
217 if (buf[0] == '\0') {
218 snprintf(buf, buflen,
219 "%s %ju/sec (%.2f%%)",
220 name, (uintmax_t)(step / delta_sec),
221 percent_time(spent, delta_usec));
222 } else {
223 printf("%-40s %s %ju/sec (%.2f%%)\n",
224 buf, name, (uintmax_t)(step / delta_sec),
225 percent_time(spent, delta_usec));
226 buf[0] = '\0';
230 return count;
233 static uint64_t print_count_samples(
234 const struct profile_stats * const current,
235 const struct profile_stats * const last,
236 uint64_t delta_usec)
238 uint64_t count = 0;
239 char buf[40] = { '\0', };
241 if (delta_usec == 0) {
242 return 0;
245 #define SMBPROFILE_STATS_START
246 #define SMBPROFILE_STATS_SECTION_START(name)
247 #define SMBPROFILE_STATS_COUNT(name) do { \
248 count += print_count_count_samples(buf, sizeof(buf), \
249 #name, \
250 &current->name##_stats, \
251 &last->name##_stats, \
252 delta_usec); \
253 } while(0);
254 #define SMBPROFILE_STATS_TIME(name) do { \
255 } while(0);
256 #define SMBPROFILE_STATS_BASIC(name) do { \
257 count += print_basic_count_samples(buf, sizeof(buf), \
258 #name, \
259 &current->name##_stats, \
260 &last->name##_stats, \
261 delta_usec); \
262 } while(0);
263 #define SMBPROFILE_STATS_BYTES(name) do { \
264 count += print_bytes_count_samples(buf, sizeof(buf), \
265 #name, \
266 &current->name##_stats, \
267 &last->name##_stats, \
268 delta_usec); \
269 } while(0);
270 #define SMBPROFILE_STATS_IOBYTES(name) do { \
271 count += print_iobytes_count_samples(buf, sizeof(buf), \
272 #name, \
273 &current->name##_stats, \
274 &last->name##_stats, \
275 delta_usec); \
276 } while(0);
277 #define SMBPROFILE_STATS_SECTION_END
278 #define SMBPROFILE_STATS_END
279 SMBPROFILE_STATS_ALL_SECTIONS
280 #undef SMBPROFILE_STATS_START
281 #undef SMBPROFILE_STATS_SECTION_START
282 #undef SMBPROFILE_STATS_COUNT
283 #undef SMBPROFILE_STATS_TIME
284 #undef SMBPROFILE_STATS_BASIC
285 #undef SMBPROFILE_STATS_BYTES
286 #undef SMBPROFILE_STATS_IOBYTES
287 #undef SMBPROFILE_STATS_SECTION_END
288 #undef SMBPROFILE_STATS_END
290 if (buf[0] != '\0') {
291 printf("%-40s\n", buf);
292 buf[0] = '\0';
295 return count;
298 static struct profile_stats sample_data[2];
299 static uint64_t sample_time[2];
301 bool status_profile_rates(bool verbose)
303 uint64_t remain_usec;
304 uint64_t next_usec;
305 uint64_t delta_usec;
307 int last = 0;
308 int current = 1;
309 int tmp;
311 if (verbose) {
312 fprintf(stderr, "Sampling stats at %d sec intervals\n",
313 usec_to_sec(sample_interval_usec));
316 if (!profile_setup(NULL, True)) {
317 fprintf(stderr,"Failed to initialise profile memory\n");
318 return False;
321 memcpy(&sample_data[last], profile_p, sizeof(*profile_p));
322 for (;;) {
323 sample_time[current] = profile_timestamp();
324 next_usec = sample_time[current] + sample_interval_usec;
326 /* Take a sample. */
327 memcpy(&sample_data[current], profile_p, sizeof(*profile_p));
329 /* Rate convert some values and print results. */
330 delta_usec = sample_time[current] - sample_time[last];
332 if (print_count_samples(&sample_data[current],
333 &sample_data[last], delta_usec)) {
334 printf("\n");
337 /* Swap sampling buffers. */
338 tmp = last;
339 last = current;
340 current = tmp;
342 /* Delay until next sample time. */
343 remain_usec = next_usec - profile_timestamp();
344 if (remain_usec > sample_interval_usec) {
345 fprintf(stderr, "eek! falling behind sampling rate!\n");
346 } else {
347 if (verbose) {
348 fprintf(stderr,
349 "delaying for %lu msec\n",
350 (unsigned long )usec_to_msec(remain_usec));
353 usleep(remain_usec);
358 return True;