1
+ #include <pthread.h>
2
+ #include <stdint.h>
3
+ #include <stdio.h>
4
+ #include <string.h>
5
+ #include <time.h>
6
+
7
+ #include "zenoh.h"
8
+
9
+ pthread_cond_t cond ;
10
+ pthread_mutex_t mutex ;
11
+
12
+ void callback (const z_sample_t * sample , void * context ) { pthread_cond_signal (& cond ); }
13
+ void drop (void * context ) { pthread_cond_destroy (& cond ); }
14
+
15
+ struct args_t {
16
+ unsigned int size ; // -s
17
+ unsigned int number_of_pings ; // -n
18
+ unsigned int warmup_ms ; // -w
19
+ char * config_path ; // -c
20
+ uint8_t help_requested ; // -h
21
+ };
22
+ struct args_t parse_args (int argc , char * * argv );
23
+
24
+ int main (int argc , char * * argv ) {
25
+ struct args_t args = parse_args (argc , argv );
26
+ if (args .help_requested ) {
27
+ printf (
28
+ "\
29
+ -n (optional, int, default=4): the number of pings to be attempted\n\
30
+ -s (optional, int, default=8): the size of the payload embedded in the ping and repeated by the pong\n\
31
+ -w (optional, int, default=0): the warmup time in ms during which pings will be emitted but not measured\n\
32
+ -c (optional, string): the path to a configuration file for the session. If this option isn't passed, the default configuration will be used.\n\
33
+ " );
34
+ return 1 ;
35
+ }
36
+ pthread_mutex_init (& mutex , NULL );
37
+ pthread_cond_init (& cond , NULL );
38
+ z_owned_config_t config = args .config_path ? zc_config_from_file (args .config_path ) : z_config_default ();
39
+ z_owned_session_t session = z_open (z_move (config ));
40
+ z_keyexpr_t ping = z_keyexpr_unchecked ("test/ping" );
41
+ z_keyexpr_t pong = z_keyexpr_unchecked ("test/pong" );
42
+ z_owned_publisher_t pub = z_declare_publisher (z_loan (session ), ping , NULL );
43
+ z_owned_closure_sample_t respond = z_closure (callback , drop , (void * )(& pub ));
44
+ z_owned_subscriber_t sub = z_declare_subscriber (z_loan (session ), pong , z_move (respond ), NULL );
45
+ uint8_t * data = malloc (args .size );
46
+ for (int i = 0 ; i < args .size ; i ++ ) {
47
+ data [i ] = i % 10 ;
48
+ }
49
+ pthread_mutex_lock (& mutex );
50
+ if (args .warmup_ms ) {
51
+ printf ("Warming up for %dms...\n" , args .warmup_ms );
52
+ clock_t warmup_end = clock () + CLOCKS_PER_SEC * args .warmup_ms / 1000 ;
53
+ for (clock_t now = clock (); now < warmup_end ; now = clock ()) {
54
+ z_publisher_put (z_loan (pub ), data , args .size , NULL );
55
+ pthread_cond_wait (& cond , & mutex );
56
+ }
57
+ }
58
+ clock_t * results = malloc (sizeof (clock_t ) * args .number_of_pings );
59
+ for (int i = 0 ; i < args .number_of_pings ; i ++ ) {
60
+ clock_t start = clock ();
61
+ z_publisher_put (z_loan (pub ), data , args .size , NULL );
62
+ pthread_cond_wait (& cond , & mutex );
63
+ clock_t end = clock ();
64
+ results [i ] = end - start ;
65
+ }
66
+ for (int i = 0 ; i < args .number_of_pings ; i ++ ) {
67
+ clock_t rtt = results [i ] * 1000000 / CLOCKS_PER_SEC ;
68
+ printf ("%d bytes: seq=%d rtt=%ldµs lat=%ldµs\n" , args .size , i , rtt , rtt / 2 );
69
+ }
70
+ pthread_mutex_unlock (& mutex );
71
+ free (results );
72
+ free (data );
73
+ z_drop (z_move (sub ));
74
+ z_drop (z_move (pub ));
75
+ z_close (z_move (session ));
76
+ }
77
+
78
+ char * getopt (int argc , char * * argv , char option ) {
79
+ for (int i = 0 ; i < argc ; i ++ ) {
80
+ size_t len = strlen (argv [i ]);
81
+ if (len >= 2 && argv [i ][0 ] == '-' && argv [i ][1 ] == option ) {
82
+ if (len > 2 && argv [i ][2 ] == '=' ) {
83
+ return argv [i ] + 3 ;
84
+ } else if (i + 1 < argc ) {
85
+ return argv [i + 1 ];
86
+ }
87
+ }
88
+ }
89
+ return NULL ;
90
+ }
91
+
92
+ struct args_t parse_args (int argc , char * * argv ) {
93
+ for (int i = 0 ; i < argc ; i ++ ) {
94
+ if (strcmp (argv [i ], "-h" ) == 0 ) {
95
+ return (struct args_t ){.help_requested = 1 };
96
+ }
97
+ }
98
+ char * arg = getopt (argc , argv , 's' );
99
+ unsigned int size = 8 ;
100
+ if (arg ) {
101
+ size = atoi (arg );
102
+ }
103
+ arg = getopt (argc , argv , 'n' );
104
+ unsigned int number_of_pings = 4 ;
105
+ if (arg ) {
106
+ number_of_pings = atoi (arg );
107
+ }
108
+ arg = getopt (argc , argv , 'w' );
109
+ unsigned int warmup_ms = 0 ;
110
+ if (arg ) {
111
+ warmup_ms = atoi (arg );
112
+ }
113
+ return (struct args_t ){.help_requested = 0 ,
114
+ .size = size ,
115
+ .number_of_pings = number_of_pings ,
116
+ .warmup_ms = warmup_ms ,
117
+ .config_path = getopt (argc , argv , 'c' )};
118
+ }
0 commit comments