VERSION: Disable GIT_SNAPSHOT for the 4.11.8 release.
[Samba.git] / source3 / utils / status_profile.c
blob829e84cef1c22bb2c0db3de9a610b13e38d0b4a8
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 struct profile_stats stats = {};
47 if (!profile_setup(NULL, True)) {
48 fprintf(stderr,"Failed to initialise profile memory\n");
49 return False;
52 smbprofile_collect(&stats);
54 #define __PRINT_FIELD_LINE(name, _stats, field) do { \
55 d_printf("%-59s%20ju\n", \
56 name "_" #field ":", \
57 (uintmax_t)stats.values._stats.field); \
58 } while(0);
59 #define SMBPROFILE_STATS_START
60 #define SMBPROFILE_STATS_SECTION_START(name, display) profile_separator(#display);
61 #define SMBPROFILE_STATS_COUNT(name) do { \
62 __PRINT_FIELD_LINE(#name, name##_stats, count); \
63 } while(0);
64 #define SMBPROFILE_STATS_TIME(name) do { \
65 __PRINT_FIELD_LINE(#name, name##_stats, time); \
66 } while(0);
67 #define SMBPROFILE_STATS_BASIC(name) do { \
68 __PRINT_FIELD_LINE(#name, name##_stats, count); \
69 __PRINT_FIELD_LINE(#name, name##_stats, time); \
70 } while(0);
71 #define SMBPROFILE_STATS_BYTES(name) do { \
72 __PRINT_FIELD_LINE(#name, name##_stats, count); \
73 __PRINT_FIELD_LINE(#name, name##_stats, time); \
74 __PRINT_FIELD_LINE(#name, name##_stats, idle); \
75 __PRINT_FIELD_LINE(#name, name##_stats, bytes); \
76 } while(0);
77 #define SMBPROFILE_STATS_IOBYTES(name) do { \
78 __PRINT_FIELD_LINE(#name, name##_stats, count); \
79 __PRINT_FIELD_LINE(#name, name##_stats, time); \
80 __PRINT_FIELD_LINE(#name, name##_stats, idle); \
81 __PRINT_FIELD_LINE(#name, name##_stats, inbytes); \
82 __PRINT_FIELD_LINE(#name, name##_stats, outbytes); \
83 } while(0);
84 #define SMBPROFILE_STATS_SECTION_END
85 #define SMBPROFILE_STATS_END
86 SMBPROFILE_STATS_ALL_SECTIONS
87 #undef __PRINT_FIELD_LINE
88 #undef SMBPROFILE_STATS_START
89 #undef SMBPROFILE_STATS_SECTION_START
90 #undef SMBPROFILE_STATS_COUNT
91 #undef SMBPROFILE_STATS_TIME
92 #undef SMBPROFILE_STATS_BASIC
93 #undef SMBPROFILE_STATS_BYTES
94 #undef SMBPROFILE_STATS_IOBYTES
95 #undef SMBPROFILE_STATS_SECTION_END
96 #undef SMBPROFILE_STATS_END
98 return True;
101 /* Convert microseconds to milliseconds. */
102 #define usec_to_msec(s) ((s) / 1000)
103 /* Convert microseconds to seconds. */
104 #define usec_to_sec(s) ((s) / 1000000)
105 /* One second in microseconds. */
106 #define one_second_usec (1000000)
108 #define sample_interval_usec one_second_usec
110 #define percent_time(used, period) ((double)(used) / (double)(period) * 100.0 )
112 static uint64_t print_count_count_samples(
113 char *buf, const size_t buflen,
114 const char *name,
115 const struct smbprofile_stats_count * const current,
116 const struct smbprofile_stats_count * const last,
117 uint64_t delta_usec)
119 uint64_t step = current->count - last->count;
120 uint64_t count = 0;
122 if (step != 0) {
123 uint64_t delta_sec = usec_to_sec(delta_usec);
125 count++;
127 if (buf[0] == '\0') {
128 snprintf(buf, buflen,
129 "%-40s %ju/sec",
130 name, (uintmax_t)(step / delta_sec));
131 } else {
132 printf("%-40s %s %ju/sec\n",
133 buf, name, (uintmax_t)(step / delta_sec));
134 buf[0] = '\0';
138 return count;
141 static uint64_t print_basic_count_samples(
142 char *buf, const size_t buflen,
143 const char *name,
144 const struct smbprofile_stats_basic * const current,
145 const struct smbprofile_stats_basic * const last,
146 uint64_t delta_usec)
148 uint64_t step = current->count - last->count;
149 uint64_t spent = current->time - last->time;
150 uint64_t count = 0;
152 if (step != 0) {
153 uint64_t delta_sec = usec_to_sec(delta_usec);
155 count++;
157 if (buf[0] == '\0') {
158 snprintf(buf, buflen,
159 "%s %ju/sec (%.2f%%)",
160 name, (uintmax_t)(step / delta_sec),
161 percent_time(spent, delta_usec));
162 } else {
163 printf("%-40s %s %ju/sec (%.2f%%)\n",
164 buf, name, (uintmax_t)(step / delta_sec),
165 percent_time(spent, delta_usec));
166 buf[0] = '\0';
170 return count;
173 static uint64_t print_bytes_count_samples(
174 char *buf, const size_t buflen,
175 const char *name,
176 const struct smbprofile_stats_bytes * const current,
177 const struct smbprofile_stats_bytes * const last,
178 uint64_t delta_usec)
180 uint64_t step = current->count - last->count;
181 uint64_t spent = current->time - last->time;
182 uint64_t count = 0;
184 if (step != 0) {
185 uint64_t delta_sec = usec_to_sec(delta_usec);
187 count++;
189 if (buf[0] == '\0') {
190 snprintf(buf, buflen,
191 "%s %ju/sec (%.2f%%)",
192 name, (uintmax_t)(step / delta_sec),
193 percent_time(spent, delta_usec));
194 } else {
195 printf("%-40s %s %ju/sec (%.2f%%)\n",
196 buf, name, (uintmax_t)(step / delta_sec),
197 percent_time(spent, delta_usec));
198 buf[0] = '\0';
202 return count;
205 static uint64_t print_iobytes_count_samples(
206 char *buf, const size_t buflen,
207 const char *name,
208 const struct smbprofile_stats_iobytes * const current,
209 const struct smbprofile_stats_iobytes * const last,
210 uint64_t delta_usec)
212 uint64_t step = current->count - last->count;
213 uint64_t spent = current->time - last->time;
214 uint64_t count = 0;
216 if (step != 0) {
217 uint64_t delta_sec = usec_to_sec(delta_usec);
219 count++;
221 if (buf[0] == '\0') {
222 snprintf(buf, buflen,
223 "%s %ju/sec (%.2f%%)",
224 name, (uintmax_t)(step / delta_sec),
225 percent_time(spent, delta_usec));
226 } else {
227 printf("%-40s %s %ju/sec (%.2f%%)\n",
228 buf, name, (uintmax_t)(step / delta_sec),
229 percent_time(spent, delta_usec));
230 buf[0] = '\0';
234 return count;
237 static uint64_t print_count_samples(
238 const struct profile_stats * const current,
239 const struct profile_stats * const last,
240 uint64_t delta_usec)
242 uint64_t count = 0;
243 char buf[60] = { '\0', };
245 if (delta_usec == 0) {
246 return 0;
249 #define SMBPROFILE_STATS_START
250 #define SMBPROFILE_STATS_SECTION_START(name, display)
251 #define SMBPROFILE_STATS_COUNT(name) do { \
252 count += print_count_count_samples(buf, sizeof(buf), \
253 #name, \
254 &current->values.name##_stats, \
255 &last->values.name##_stats, \
256 delta_usec); \
257 } while(0);
258 #define SMBPROFILE_STATS_TIME(name) do { \
259 } while(0);
260 #define SMBPROFILE_STATS_BASIC(name) do { \
261 count += print_basic_count_samples(buf, sizeof(buf), \
262 #name, \
263 &current->values.name##_stats, \
264 &last->values.name##_stats, \
265 delta_usec); \
266 } while(0);
267 #define SMBPROFILE_STATS_BYTES(name) do { \
268 count += print_bytes_count_samples(buf, sizeof(buf), \
269 #name, \
270 &current->values.name##_stats, \
271 &last->values.name##_stats, \
272 delta_usec); \
273 } while(0);
274 #define SMBPROFILE_STATS_IOBYTES(name) do { \
275 count += print_iobytes_count_samples(buf, sizeof(buf), \
276 #name, \
277 &current->values.name##_stats, \
278 &last->values.name##_stats, \
279 delta_usec); \
280 } while(0);
281 #define SMBPROFILE_STATS_SECTION_END
282 #define SMBPROFILE_STATS_END
283 SMBPROFILE_STATS_ALL_SECTIONS
284 #undef SMBPROFILE_STATS_START
285 #undef SMBPROFILE_STATS_SECTION_START
286 #undef SMBPROFILE_STATS_COUNT
287 #undef SMBPROFILE_STATS_TIME
288 #undef SMBPROFILE_STATS_BASIC
289 #undef SMBPROFILE_STATS_BYTES
290 #undef SMBPROFILE_STATS_IOBYTES
291 #undef SMBPROFILE_STATS_SECTION_END
292 #undef SMBPROFILE_STATS_END
294 if (buf[0] != '\0') {
295 printf("%-40s\n", buf);
296 buf[0] = '\0';
299 return count;
302 static struct profile_stats sample_data[2];
303 static uint64_t sample_time[2];
305 bool status_profile_rates(bool verbose)
307 uint64_t remain_usec;
308 uint64_t next_usec;
309 uint64_t delta_usec;
311 int last = 0;
312 int current = 1;
313 int tmp;
315 if (verbose) {
316 fprintf(stderr, "Sampling stats at %d sec intervals\n",
317 usec_to_sec(sample_interval_usec));
320 if (!profile_setup(NULL, True)) {
321 fprintf(stderr,"Failed to initialise profile memory\n");
322 return False;
325 smbprofile_collect(&sample_data[last]);
326 for (;;) {
327 sample_time[current] = profile_timestamp();
328 next_usec = sample_time[current] + sample_interval_usec;
330 /* Take a sample. */
331 smbprofile_collect(&sample_data[current]);
333 /* Rate convert some values and print results. */
334 delta_usec = sample_time[current] - sample_time[last];
336 if (print_count_samples(&sample_data[current],
337 &sample_data[last], delta_usec)) {
338 printf("\n");
341 /* Swap sampling buffers. */
342 tmp = last;
343 last = current;
344 current = tmp;
346 /* Delay until next sample time. */
347 remain_usec = next_usec - profile_timestamp();
348 if (remain_usec > sample_interval_usec) {
349 fprintf(stderr, "eek! falling behind sampling rate!\n");
350 } else {
351 if (verbose) {
352 fprintf(stderr,
353 "delaying for %lu msec\n",
354 (unsigned long )usec_to_msec(remain_usec));
357 usleep(remain_usec);
362 return True;