#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,
int optflag;
int mode;
int n;
+ struct timeval timeo;
struct cegw_if ceif[2]; /* 0 -> src, 1 -> dst */
};
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 );
}
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;
}
/**
- * can_sock_create()
+ * can_sock_create
* @return can socket fd, or -1 on failure
*/
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 )
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[] =
{
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 )
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;
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;
{
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 );
}
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 );