source: mainline/uspace/app/tmon/burst_tests.c@ acb9aa7

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since acb9aa7 was acb9aa7, checked in by Petr Mánek <petr.manek@…>, 8 years ago

tmon: format data size

  • Property mode set to 100644
File size: 8.8 KB
Line 
1/*
2 * Copyright (c) 2017 Petr Manek
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup tmon
30 * @{
31 */
32/**
33 * @file
34 * USB burst tests.
35 */
36
37#include <stdio.h>
38#include <errno.h>
39#include <str_error.h>
40#include <getopt.h>
41#include <usbdiag_iface.h>
42#include "commands.h"
43#include "tf.h"
44
45#define NAME "tmon"
46#define INDENT " "
47
48typedef struct tmon_burst_test_params {
49 tmon_test_params_t base; /* inheritance */
50 uint32_t cycles;
51 size_t size;
52} tmon_burst_test_params_t;
53
54static struct option long_options[] = {
55 {"cycles", required_argument, NULL, 'n'},
56 {"size", required_argument, NULL, 's'},
57 {0, 0, NULL, 0}
58};
59
60static const char *short_options = "n:s:";
61
62static int read_params(int argc, char *argv[], tmon_test_params_t **params)
63{
64 int rc;
65 tmon_burst_test_params_t *p = (tmon_burst_test_params_t *) malloc(sizeof(tmon_burst_test_params_t));
66 if (!p)
67 return ENOMEM;
68
69 // Default values.
70 p->cycles = 256;
71 p->size = 1024;
72
73 // Parse other than default values.
74 int c;
75 for (c = 0, optreset = 1, optind = 0; c != -1;) {
76 c = getopt_long(argc, argv, short_options, long_options, NULL);
77 switch (c) {
78 case -1:
79 break;
80 case 'n':
81 if (!optarg || str_uint32_t(optarg, NULL, 10, false, &p->cycles) != EOK) {
82 puts(NAME ": Invalid number of cycles.\n");
83 rc = EINVAL;
84 goto err_malloc;
85 }
86 break;
87 case 's':
88 if (!optarg || str_size_t(optarg, NULL, 10, false, &p->size) != EOK) {
89 puts(NAME ": Invalid data size.\n");
90 rc = EINVAL;
91 goto err_malloc;
92 }
93 break;
94 }
95 }
96
97 *params = (tmon_test_params_t *) p;
98 return EOK;
99
100err_malloc:
101 free(p);
102 *params = NULL;
103 return rc;
104}
105
106typedef struct tmon_unit {
107 char prefix;
108 uint64_t factor;
109} tmon_unit_t;
110
111static const tmon_unit_t units[] = {
112 { .prefix = 'E', .factor = 1ul << 60 },
113 { .prefix = 'P', .factor = 1ul << 50 },
114 { .prefix = 'T', .factor = 1ul << 40 },
115 { .prefix = 'G', .factor = 1ul << 30 },
116 { .prefix = 'M', .factor = 1ul << 20 },
117 { .prefix = 'k', .factor = 1ul << 10 },
118 { /* NULL-terminated */ }
119};
120
121static char * format_size(double size, const char *fmt)
122{
123 int i;
124 for (i = 0; units[i].prefix; ++i) {
125 if (units[i].factor <= size)
126 break;
127 }
128
129 char prefix[2] = { '\0', '\0' };
130 double factor = 1;
131
132 if (units[i].prefix) {
133 prefix[0] = units[i].prefix;
134 factor = units[i].factor;
135 }
136
137 const double div_size = size / factor;
138 char *out = NULL;
139 asprintf(&out, fmt, div_size, prefix);
140
141 return out;
142}
143
144static void print_params(const tmon_burst_test_params_t *params)
145{
146 printf(INDENT "Number of cycles: %d\n", params->cycles);
147
148 char *str_size = format_size(params->size, "%0.3f %sB");
149 printf(INDENT "Data size: %s\n", str_size);
150 free(str_size);
151}
152
153static void print_results(const tmon_burst_test_params_t *params, usbdiag_dur_t duration)
154{
155 printf(INDENT "Total duration: %ld ms\n", duration);
156
157 const double dur_per_cycle = (double) duration / (double) params->cycles;
158 printf(INDENT "Duration per cycle: %0.3f ms\n", dur_per_cycle);
159
160 const size_t total_size = params->size * params->cycles;
161 char *str_total_size = format_size(total_size, "%0.3f %sB");
162 printf(INDENT "Total size: %s\n", str_total_size);
163 free(str_total_size);
164
165 const double speed = 1000.0 * (double) total_size / (double) duration;
166 char *str_speed = format_size(speed, "%0.3f %sB/s");
167 printf(INDENT "Average speed: %s\n", str_speed);
168 free(str_speed);
169}
170
171static int run_intr_in(async_exch_t *exch, const tmon_test_params_t *generic_params)
172{
173 const tmon_burst_test_params_t *params = (tmon_burst_test_params_t *) generic_params;
174 puts("Reading data from interrupt endpoint.\n");
175 print_params(params);
176
177 usbdiag_dur_t duration;
178 int rc = usbdiag_burst_intr_in(exch, params->cycles, params->size, &duration);
179 if (rc) {
180 printf(NAME ": Test failed with error: %s\n", str_error(rc));
181 return 1;
182 }
183
184 puts("Test succeeded.\n");
185 print_results(params, duration);
186 return 0;
187}
188
189static int run_intr_out(async_exch_t *exch, const tmon_test_params_t *generic_params)
190{
191 const tmon_burst_test_params_t *params = (tmon_burst_test_params_t *) generic_params;
192 puts("Writing data to interrupt endpoint.\n");
193 print_params(params);
194
195 usbdiag_dur_t duration;
196 int rc = usbdiag_burst_intr_out(exch, params->cycles, params->size, &duration);
197 if (rc) {
198 printf(NAME ": Test failed with error: %s\n", str_error(rc));
199 return 1;
200 }
201
202 puts("Test succeeded.\n");
203 print_results(params, duration);
204 return 0;
205}
206
207static int run_bulk_in(async_exch_t *exch, const tmon_test_params_t *generic_params)
208{
209 const tmon_burst_test_params_t *params = (tmon_burst_test_params_t *) generic_params;
210 puts("Reading data from bulk endpoint.\n");
211 print_params(params);
212
213 usbdiag_dur_t duration;
214 int rc = usbdiag_burst_bulk_in(exch, params->cycles, params->size, &duration);
215 if (rc) {
216 printf(NAME ": Test failed with error: %s\n", str_error(rc));
217 return 1;
218 }
219
220 puts("Test succeeded.\n");
221 print_results(params, duration);
222 return 0;
223}
224
225static int run_bulk_out(async_exch_t *exch, const tmon_test_params_t *generic_params)
226{
227 const tmon_burst_test_params_t *params = (tmon_burst_test_params_t *) generic_params;
228 puts("Writing data to bulk endpoint.\n");
229 print_params(params);
230
231 usbdiag_dur_t duration;
232 int rc = usbdiag_burst_bulk_out(exch, params->cycles, params->size, &duration);
233 if (rc) {
234 printf(NAME ": Test failed with error: %s\n", str_error(rc));
235 return 1;
236 }
237
238 puts("Test succeeded.\n");
239 print_results(params, duration);
240 return 0;
241}
242
243static int run_isoch_in(async_exch_t *exch, const tmon_test_params_t *generic_params)
244{
245 const tmon_burst_test_params_t *params = (tmon_burst_test_params_t *) generic_params;
246 puts("Reading data from isochronous endpoint.\n");
247 print_params(params);
248
249 usbdiag_dur_t duration;
250 int rc = usbdiag_burst_isoch_in(exch, params->cycles, params->size, &duration);
251 if (rc) {
252 printf(NAME ": Test failed with error: %s\n", str_error(rc));
253 return 1;
254 }
255
256 puts("Test succeeded.\n");
257 print_results(params, duration);
258 return 0;
259}
260
261static int run_isoch_out(async_exch_t *exch, const tmon_test_params_t *generic_params)
262{
263 const tmon_burst_test_params_t *params = (tmon_burst_test_params_t *) generic_params;
264 puts("Writing data to isochronous endpoint.\n");
265 print_params(params);
266
267 usbdiag_dur_t duration;
268 int rc = usbdiag_burst_isoch_out(exch, params->cycles, params->size, &duration);
269 if (rc) {
270 printf(NAME ": Test failed with error: %s\n", str_error(rc));
271 return 1;
272 }
273
274 puts("Test succeeded.\n");
275 print_results(params, duration);
276 return 0;
277}
278
279int tmon_burst_intr_in(int argc, char *argv[])
280{
281 static const tmon_test_ops_t ops = {
282 .run = run_intr_in,
283 .read_params = read_params
284 };
285
286 return tmon_test_main(argc, argv, &ops);
287}
288
289int tmon_burst_intr_out(int argc, char *argv[])
290{
291 static const tmon_test_ops_t ops = {
292 .run = run_intr_out,
293 .read_params = read_params
294 };
295
296 return tmon_test_main(argc, argv, &ops);
297}
298
299int tmon_burst_bulk_in(int argc, char *argv[])
300{
301 static const tmon_test_ops_t ops = {
302 .run = run_bulk_in,
303 .read_params = read_params
304 };
305
306 return tmon_test_main(argc, argv, &ops);
307}
308
309int tmon_burst_bulk_out(int argc, char *argv[])
310{
311 static const tmon_test_ops_t ops = {
312 .run = run_bulk_out,
313 .read_params = read_params
314 };
315
316 return tmon_test_main(argc, argv, &ops);
317}
318
319int tmon_burst_isoch_in(int argc, char *argv[])
320{
321 static const tmon_test_ops_t ops = {
322 .run = run_isoch_in,
323 .read_params = read_params
324 };
325
326 return tmon_test_main(argc, argv, &ops);
327}
328
329int tmon_burst_isoch_out(int argc, char *argv[])
330{
331 static const tmon_test_ops_t ops = {
332 .run = run_isoch_out,
333 .read_params = read_params
334 };
335
336 return tmon_test_main(argc, argv, &ops);
337}
338
339/** @}
340 */
Note: See TracBrowser for help on using the repository browser.