2 * Unix SMB/CIFS implementation.
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/>.
22 #include "smbprofile.h"
23 #include "status_profile.h"
25 static void profile_separator(const char * title
)
30 snprintf(line
, sizeof(line
), "**** %s ", title
);
32 for (end
= line
+ strlen(line
); end
< &line
[sizeof(line
) -1]; ++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");
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); \
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); \
64 #define SMBPROFILE_STATS_TIME(name) do { \
65 __PRINT_FIELD_LINE(#name, name##_stats, time); \
67 #define SMBPROFILE_STATS_BASIC(name) do { \
68 __PRINT_FIELD_LINE(#name, name##_stats, count); \
69 __PRINT_FIELD_LINE(#name, name##_stats, time); \
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); \
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); \
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
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
,
115 const struct smbprofile_stats_count
* const current
,
116 const struct smbprofile_stats_count
* const last
,
119 uint64_t step
= current
->count
- last
->count
;
123 uint64_t delta_sec
= usec_to_sec(delta_usec
);
127 if (buf
[0] == '\0') {
128 snprintf(buf
, buflen
,
130 name
, (uintmax_t)(step
/ delta_sec
));
132 printf("%-40s %s %ju/sec\n",
133 buf
, name
, (uintmax_t)(step
/ delta_sec
));
141 static uint64_t print_basic_count_samples(
142 char *buf
, const size_t buflen
,
144 const struct smbprofile_stats_basic
* const current
,
145 const struct smbprofile_stats_basic
* const last
,
148 uint64_t step
= current
->count
- last
->count
;
149 uint64_t spent
= current
->time
- last
->time
;
153 uint64_t delta_sec
= usec_to_sec(delta_usec
);
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
));
163 printf("%-40s %s %ju/sec (%.2f%%)\n",
164 buf
, name
, (uintmax_t)(step
/ delta_sec
),
165 percent_time(spent
, delta_usec
));
173 static uint64_t print_bytes_count_samples(
174 char *buf
, const size_t buflen
,
176 const struct smbprofile_stats_bytes
* const current
,
177 const struct smbprofile_stats_bytes
* const last
,
180 uint64_t step
= current
->count
- last
->count
;
181 uint64_t spent
= current
->time
- last
->time
;
185 uint64_t delta_sec
= usec_to_sec(delta_usec
);
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
));
195 printf("%-40s %s %ju/sec (%.2f%%)\n",
196 buf
, name
, (uintmax_t)(step
/ delta_sec
),
197 percent_time(spent
, delta_usec
));
205 static uint64_t print_iobytes_count_samples(
206 char *buf
, const size_t buflen
,
208 const struct smbprofile_stats_iobytes
* const current
,
209 const struct smbprofile_stats_iobytes
* const last
,
212 uint64_t step
= current
->count
- last
->count
;
213 uint64_t spent
= current
->time
- last
->time
;
217 uint64_t delta_sec
= usec_to_sec(delta_usec
);
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
));
227 printf("%-40s %s %ju/sec (%.2f%%)\n",
228 buf
, name
, (uintmax_t)(step
/ delta_sec
),
229 percent_time(spent
, delta_usec
));
237 static uint64_t print_count_samples(
238 const struct profile_stats
* const current
,
239 const struct profile_stats
* const last
,
243 char buf
[40] = { '\0', };
245 if (delta_usec
== 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), \
254 ¤t->values.name##_stats, \
255 &last->values.name##_stats, \
258 #define SMBPROFILE_STATS_TIME(name) do { \
260 #define SMBPROFILE_STATS_BASIC(name) do { \
261 count += print_basic_count_samples(buf, sizeof(buf), \
263 ¤t->values.name##_stats, \
264 &last->values.name##_stats, \
267 #define SMBPROFILE_STATS_BYTES(name) do { \
268 count += print_bytes_count_samples(buf, sizeof(buf), \
270 ¤t->values.name##_stats, \
271 &last->values.name##_stats, \
274 #define SMBPROFILE_STATS_IOBYTES(name) do { \
275 count += print_iobytes_count_samples(buf, sizeof(buf), \
277 ¤t->values.name##_stats, \
278 &last->values.name##_stats, \
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
);
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
;
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");
325 smbprofile_collect(&sample_data
[last
]);
327 sample_time
[current
] = profile_timestamp();
328 next_usec
= sample_time
[current
] + sample_interval_usec
;
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
)) {
341 /* Swap sampling buffers. */
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");
353 "delaying for %lu msec\n",
354 (unsigned long )usec_to_msec(remain_usec
));