2323#include <errno.h>
2424#include <getopt.h>
2525#include <iio.h>
26+ #include <inttypes.h>
2627#include <signal.h>
2728#include <stdio.h>
2829#include <string.h>
4243
4344#define SAMPLES_PER_READ 256
4445#define DEFAULT_FREQ_HZ 100
46+ #define REFILL_PER_BENCHMARK 10
4547
4648static const struct option options [] = {
4749 {"trigger" , required_argument , 0 , 't' },
4850 {"buffer-size" , required_argument , 0 , 'b' },
4951 {"samples" , required_argument , 0 , 's' },
5052 {"auto" , no_argument , 0 , 'a' },
5153 {"cyclic" , no_argument , 0 , 'c' },
54+ {"benchmark" , no_argument , 0 , 'B' },
5255 {0 , 0 , 0 , 0 },
5356};
5457
@@ -61,6 +64,8 @@ static const char *options_descriptions[] = {
6164 "Number of samples to write, 0 = infinite. Default is 0." ,
6265 "Scan for available contexts and if only one is available use it." ,
6366 "Use cyclic buffer mode." ,
67+ "Benchmark throughput."
68+ "\n\t\t\tStatistics will be printed on the standard input." ,
6469};
6570
6671static struct iio_context * ctx ;
@@ -196,7 +201,7 @@ static ssize_t read_sample(const struct iio_channel *chn,
196201 return (ssize_t ) nb ;
197202}
198203
199- #define MY_OPTS "t:b:s:T:ac "
204+ #define MY_OPTS "t:b:s:T:acB "
200205
201206int main (int argc , char * * argv )
202207{
@@ -207,9 +212,10 @@ int main(int argc, char **argv)
207212 int c ;
208213 struct iio_device * dev ;
209214 ssize_t sample_size ;
210- bool cyclic_buffer = false;
215+ bool mib , cyclic_buffer = false, benchmark = false;
211216 ssize_t ret ;
212217 struct option * opts ;
218+ uint64_t before , after , rate , total ;
213219
214220 argw = dup_argv (MY_NAME , argc , argv );
215221
@@ -249,6 +255,9 @@ int main(int argc, char **argv)
249255 }
250256 buffer_size = sanitize_clamp ("buffer size" , optarg , 1 , SIZE_MAX );
251257 break ;
258+ case 'B' :
259+ benchmark = true;
260+ break ;
252261 case 's' :
253262 if (!optarg ) {
254263 fprintf (stderr , "Number of samples requires argument\n" );
@@ -275,6 +284,12 @@ int main(int argc, char **argv)
275284 if (!ctx )
276285 return EXIT_FAILURE ;
277286
287+ if (benchmark && cyclic_buffer ) {
288+ fprintf (stderr , "Cannot benchmark in cyclic mode.\n" );
289+ iio_context_destroy (ctx );
290+ return EXIT_FAILURE ;
291+ }
292+
278293 setup_sig_handler ();
279294
280295 dev = iio_context_find_device (ctx , argw [optind ]);
@@ -381,10 +396,12 @@ int main(int argc, char **argv)
381396 _setmode (_fileno ( stdin ), _O_BINARY );
382397#endif
383398
384- while (app_running ) {
385- /* If there are only the samples we requested, we don't need to
386- * demux */
387- if (iio_buffer_step (buffer ) == sample_size ) {
399+ for (i = 0 , total = 0 ; app_running ; ) {
400+ if (benchmark ) {
401+ before = get_time_us ();
402+ } else if (iio_buffer_step (buffer ) == sample_size ) {
403+ /* If there are only the samples we requested, we don't
404+ * need to demux */
388405 void * start = iio_buffer_start (buffer );
389406 size_t write_len , len = (intptr_t ) iio_buffer_end (buffer )
390407 - (intptr_t ) start ;
@@ -424,6 +441,25 @@ int main(int argc, char **argv)
424441 break ;
425442 }
426443
444+ if (benchmark ) {
445+ after = get_time_us ();
446+ rate = buffer_size * sample_size * 1000000ull / (after - before );
447+
448+ total += rate ;
449+
450+ if (++ i == REFILL_PER_BENCHMARK ) {
451+ mib = rate > 1000000 ;
452+
453+ fprintf (stderr , "\33[2K\rThroughput: %" PRIu64 " %ciB/s" ,
454+ total / (REFILL_PER_BENCHMARK * 1000 * (mib ? 1000 : 1 )),
455+ mib ? 'M' : 'K' );
456+
457+ i = 0 ;
458+ total = 0 ;
459+ }
460+ }
461+
462+
427463 while (cyclic_buffer && app_running ) {
428464#ifdef _WIN32
429465 Sleep (1000 );
0 commit comments