]> rtime.felk.cvut.cz Git - can-eth-gw.git/blobdiff - utils/cegwbench/cegwbench.c
kernel/canethgw mutex_unlock bug fix
[can-eth-gw.git] / utils / cegwbench / cegwbench.c
index 7a93708011bbd10516821c90658c32d416d5d6e7..550566cb1144266b7b9afd13d6fc2e210568a5d2 100644 (file)
 #include "cegwerr.h"
 #include "readif.h"
 
-/**
- * ToDo:
- * [ ] consider can timestamp
- */
+//#define BENCH_DEBUG
+#ifdef BENCH_DEBUG
+#define printdbg(...) printf( __VA_ARGS__ )
+#else
+#define printdbg(...)
+#endif
 
 #define BENCH_FLAG_N 1
 #define BENCH_FLAG_SRC 2
 #define BENCH_FLAG_DST 4
+#define BENCH_FLAG_TIMEO 8
 
 enum {
        BENCH_MODE_UNDEF,
@@ -38,6 +41,7 @@ struct optdata
        int optflag;
        int mode;
        int n;
+       struct timeval timeo;
        struct cegw_if ceif[2]; /* 0 -> src, 1 -> dst */
 };
 
@@ -50,22 +54,39 @@ void* thr_recv( void* arg )
        int sock;
        struct can_frame cf;
        int i;
+       int seq;
+       int ret;
 
        if( d.ceif[1].type == IF_CAN )
                sock = can_sock_create( d.ceif[1].can.ifindex );
        else
                sock = udp_sock_create( d.ceif[1].eth.ip, d.ceif[1].eth.port );
        if( sock == -1 )
-               return NULL;
+       {
+               /* ToDo: handle */
+               return (void*)1;
+       }
+
+       ret = setsockopt( sock, SOL_SOCKET, SO_RCVTIMEO, &d.timeo, sizeof(d.timeo) );
+       if( ret != 0 )
+               return (void*)1;
 
        pthread_barrier_wait( &barrier );
 
        /* recv */
        for( i=0; i<d.n; i++ )
        {
-               recvfrom( sock, &cf, sizeof(cf), 0, NULL, 0 );
-               clock_gettime( CLOCK_REALTIME, &rx_time[cf.data[0]] );
-               printf( "recv: (id=%d)%u\n", cf.can_id, cf.data[0] );
+               ret = recvfrom( sock, &cf, sizeof(cf), 0, NULL, 0 );
+               printdbg( "ret=%d\n", ret );
+               /* ToDo: rework */
+               if( ret == -1 )
+               {
+                       puts( "cegwbench: recv timed out\n" );
+                       return (void*)1;
+               }
+               seq = *((int*)cf.data);
+               clock_gettime( CLOCK_REALTIME, &rx_time[ seq ] );
+               printdbg( "recv: cf.data=%d\n", seq );
                if( d.mode == BENCH_MODE_ONEATTIME )
                {
                        pthread_barrier_wait( &barrier );
@@ -73,13 +94,13 @@ void* thr_recv( void* arg )
        }
 
        close( sock );
-       return NULL;
+       return (void*)0;
 }
 
 int timespec_subtract( struct timespec *result, struct timespec *x, struct timespec *yy )
 {
        struct timespec ylocal = *yy, *y = &ylocal;
-       /* Perform the carry for the later subtraction by updating Y. */
+/* Perform the carry for the later subtraction by updating Y. */
        if( x->tv_nsec < y->tv_nsec )
        {
                int nsec = (y->tv_nsec - x->tv_nsec) / 1000000000 + 1;
@@ -127,7 +148,7 @@ int udp_sock_create( struct in_addr ip, unsigned int port  )
 }
 
 /**
- * can_sock_create()
+ * can_sock_create
  * @return can socket fd, or -1 on failure
  */
 int can_sock_create( int ifindex )
@@ -154,6 +175,18 @@ int can_sock_create( int ifindex )
        return can_sock;
 }
 
+void dump_arg( int argc, char* argv[] )
+{
+       int i;
+
+       putchar( '#' );
+       for( i=0; i<argc; i++ )
+       {
+               printf( "%s ", argv[i] );
+       }
+       putchar( '\n' );        
+}
+
 int read_mode( char* in )
 {
        if( strcmp( in, "asap" ) == 0 )
@@ -172,14 +205,16 @@ int main( int argc, char* argv[] )
        struct can_frame cf;
        int sock;
        pthread_t thr;
-       float mean = 0;
        float time;
+       void* thr_ret;
        int ret;
        struct timespec res;
        int i, tmp;
 
        d.optflag = 0;
        d.mode = BENCH_MODE_ASAP;
+       d.timeo.tv_sec = 0;
+       d.timeo.tv_usec = 0;
 
        struct option longopt[] =
        {
@@ -189,7 +224,7 @@ int main( int argc, char* argv[] )
 
        while( 1 )
        {
-               opt = getopt( argc, argv, "s:d:m:n:" );
+               opt = getopt( argc, argv, "s:d:m:n:t:" );
                if( opt == -1 )
                        break;
                switch( opt )
@@ -223,6 +258,15 @@ int main( int argc, char* argv[] )
                                d.optflag |= BENCH_FLAG_N;
                                d.n = atoi( optarg );
                                break;
+                       case 't':
+                               d.optflag |= BENCH_FLAG_TIMEO;
+                               if( sscanf( optarg, "%ld", &d.timeo.tv_sec ) != 1 )
+                               {
+                                       perr( "timeout mismatch" );
+                                       return -1;
+                               }
+                               d.timeo.tv_usec = 0;
+                               break;
                        case '?':
                                return -1;
                                break;
@@ -262,7 +306,7 @@ int main( int argc, char* argv[] )
        rx_time = malloc( d.n*sizeof(struct timespec) );
 
        pthread_barrier_init( &barrier, NULL, 2 );
-       pthread_create( &thr, NULL, thr_recv, NULL  );
+       pthread_create( &thr, NULL, thr_recv, &d  );
 
        /**/
        struct sockaddr* addr;
@@ -297,11 +341,11 @@ int main( int argc, char* argv[] )
        {
                cf.can_id = i;
                cf.can_dlc = 8;
-               cf.data[0] = i;
+               memcpy( cf.data, &i, sizeof(i) );
 
-               clock_gettime( CLOCK_REALTIME, &tx_time[cf.data[0]] );
-               ret = sendto( sock, &cf, sizeof(cf), 0, addr, addr_size );
-               printf( "sending(%d)\n", ret );
+               clock_gettime( CLOCK_REALTIME, &tx_time[i] );
+               ret = sendto( sock, &cf, sizeof(cf), 0, addr, addr_size ); /* ToDo: check ret */
+               printdbg( "sending(%d)\n", ret );
                if( d.mode == BENCH_MODE_ONEATTIME )
                {
                        pthread_barrier_wait( &barrier );
@@ -309,25 +353,23 @@ int main( int argc, char* argv[] )
        }
 
        close( sock ); /* ToDo: shutdown? */
-       pthread_join( thr, NULL );
+       pthread_join( thr, &thr_ret );
+
+       if( thr_ret != NULL )
+       {
+               return 1;
+       }
 
        /* results */
-       int tn = 0;
+       dump_arg( argc, argv );
        for( i=0; i<d.n; i++ )
        {
-               if( timespec_subtract( &res, &rx_time[i], &tx_time[i] ) == 0 )
-               {
-                       time = res.tv_sec*1000000000.0f + (float)res.tv_nsec;
-                       mean += time;
-                       tn++;
-                       printf( "transfer time:%fns\n", time );
-               } else
-               {
-                       printf( "transfer time: irrelevant\n" );
-               }
+               timespec_subtract( &res, &rx_time[i], &tx_time[i] );
+
+               time = res.tv_sec*1000000000.0f + (float)res.tv_nsec;
+               printf( "%f\t", time );
        }
-       mean /= tn; /* ToDo: did they arrive all? */
-       printf( "average: %fns\n", mean );
+       putchar( '\n' );
 
        pthread_barrier_destroy( &barrier );
        free( tx_time );