X-Git-Url: http://rtime.felk.cvut.cz/gitweb/can-benchmark.git/blobdiff_plain/89d198f9565e5c693252280ed8154a8cb3d131b5..05644389a630a808331c9c57d61ce02230bb235b:/ugw/ugw.c?ds=sidebyside diff --git a/ugw/ugw.c b/ugw/ugw.c index 64d00b0..0e653d3 100644 --- a/ugw/ugw.c +++ b/ugw/ugw.c @@ -20,6 +20,12 @@ #include #include #include +#include +#include + +#ifndef SO_BUSY_POLL +#define SO_BUSY_POLL 46 +#endif #define FRAME_SIZE 256 #define BLOCK_SIZE 4096 @@ -36,10 +42,13 @@ char *devout = "can1"; enum { IN_READ, IN_RECVMMSG, IN_MMAP, IN_MMAPBUSY } in_method = IN_READ; enum { WRITE, OUT_MMAP } out_method = WRITE; bool quiet = false; +int busy_poll_us = 0; +bool nonblocking = false; enum in2out { STORE_ONLY, SEND, + NOP, }; @@ -65,6 +74,8 @@ struct out_ctx { enum in2out in_read(struct in_ctx *ctx, struct can_frame *cf) { int ret = read(ctx->s, cf, sizeof(*cf)); + if (nonblocking && ret == -1 && errno == EAGAIN) + return NOP; if (ret != sizeof(*cf)) { perror("read"); exit(1); @@ -80,6 +91,16 @@ void init_read(struct in_ctx *ctx) s = CHECK(socket(PF_CAN, SOCK_RAW, CAN_RAW)); + if (nonblocking) { + int flags = CHECK(fcntl(s, F_GETFL, 0)); + CHECK(fcntl(s, F_SETFL, flags | O_NONBLOCK)); + } + + if (busy_poll_us) { + CHECK(setsockopt(s, SOL_SOCKET, SO_BUSY_POLL, + &busy_poll_us, sizeof(busy_poll_us))); + } + strncpy(ifr.ifr_name, devin, sizeof(ifr.ifr_name)); if (-1 == ioctl(s, SIOCGIFINDEX, &ifr)) { perror(devin); @@ -127,6 +148,11 @@ void init_packet_rx(struct in_ctx *ctx) s = CHECK(socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))); + if (busy_poll_us) { + CHECK(setsockopt(s, SOL_SOCKET, SO_BUSY_POLL, + &busy_poll_us, sizeof(busy_poll_us))); + } + int val = TPACKET_V2; CHECK(setsockopt(s, SOL_PACKET, PACKET_VERSION, &val, sizeof(val))); socklen_t len = sizeof(ctx->hdrlen); @@ -158,6 +184,9 @@ void init_packet_rx(struct in_ctx *ctx) int out_write(struct out_ctx *ctx, struct can_frame *cf) { + if (ctx->from_in == NOP) + return 0; + int ret = write(ctx->s, cf, sizeof(*cf)); if (ret != sizeof(*cf)) { perror("write"); @@ -194,6 +223,10 @@ int out_packet_tx(struct out_ctx *ctx, struct can_frame *cf) volatile struct tpacket2_hdr *hdr = ctx->ptr + ctx->current*FRAME_SIZE; int ret = -1; + if (ctx->from_in == NOP) + return 0; + + while (hdr->tp_status != TP_STATUS_AVAILABLE) { struct pollfd pfd = {.fd = ctx->s, .revents = 0, .events = POLLIN|POLLRDNORM|POLLERR }; @@ -304,6 +337,11 @@ void gw() while (1) { oc.from_in = in(&ic, &cf); + switch (oc.from_in) { + case SEND: stats.send++; break; + case STORE_ONLY: stats.store++; break; + case NOP: break; + } out(&oc, &cf); } } @@ -313,8 +351,14 @@ int main(int argc, char *argv[]) { int opt; - while ((opt = getopt(argc, argv, "qr:t:")) != -1) { + while ((opt = getopt(argc, argv, "b:nqr:t:")) != -1) { switch (opt) { + case 'b': + busy_poll_us = atoi(optarg); + break; + case 'n': + nonblocking = true; + break; case 'q': quiet = true; break;