diff options
author | Maxim Uvarov <maxim.uvarov@linaro.org> | 2015-08-27 15:50:59 +0300 |
---|---|---|
committer | Maxim Uvarov <maxim.uvarov@linaro.org> | 2015-08-27 15:50:59 +0300 |
commit | 8b077af2c3338166b24839ff42c47ab72f9fd538 (patch) | |
tree | 036efab84b8cdf2f12ba578a0078a74c1899ea39 /example | |
parent | 6d8b8abf3b3b4ab25f05612e495f25e6945cb617 (diff) | |
parent | c500935d7a946da32a8c0bf80b05b277dac75b34 (diff) |
Merge branch 'master' into api-next
Diffstat (limited to 'example')
-rw-r--r-- | example/generator/odp_generator.c | 185 |
1 files changed, 127 insertions, 58 deletions
diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index c1974dc9..5c2eb061 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -43,6 +43,7 @@ */ typedef struct { int cpu_count; /**< system CPU count */ + const char *mask; /**< CPU mask */ int if_count; /**< Number of interfaces to be used */ char **if_names; /**< Array of pointers to interface names */ char *if_str; /**< Storage for interface names */ @@ -101,6 +102,7 @@ static void usage(char *progname); static int scan_ip(char *buf, unsigned int *paddr); static int scan_mac(char *in, odph_ethaddr_t *des); static void tv_sub(struct timeval *recvtime, struct timeval *sendtime); +static void print_global_stats(int num_workers); /** * Sleep for the specified amount of milliseconds @@ -376,7 +378,6 @@ static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool) static void *gen_send_thread(void *arg) { int thr; - uint64_t start, now, diff; odp_pktio_t pktio; thread_args_t *thr_args; odp_queue_t outq_def; @@ -398,7 +399,6 @@ static void *gen_send_thread(void *arg) return NULL; } - start = odp_time_cycles(); printf(" [%02i] created mode: SEND\n", thr); for (;;) { int err; @@ -439,15 +439,6 @@ static void *gen_send_thread(void *arg) >= (unsigned int)args->appl.number) { break; } - - now = odp_time_cycles(); - diff = odp_time_diff_cycles(start, now); - if (odp_time_cycles_to_ns(diff) > 20 * ODP_TIME_SEC) { - start = odp_time_cycles(); - printf(" [%02i] total send: %ju\n", - thr, odp_atomic_load_u64(&counters.seq)); - fflush(stdout); - } } /* receive number of reply pks until timeout */ @@ -465,15 +456,6 @@ static void *gen_send_thread(void *arg) } } - /* print info */ - if (args->appl.mode == APPL_MODE_UDP) { - printf(" [%02i] total send: %ju\n", - thr, odp_atomic_load_u64(&counters.seq)); - } else if (args->appl.mode == APPL_MODE_PING) { - printf(" [%02i] total send: %ju total receive: %ju\n", - thr, odp_atomic_load_u64(&counters.seq), - odp_atomic_load_u64(&counters.icmp)); - } return arg; } @@ -489,7 +471,6 @@ static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) odp_packet_t pkt; char *buf; odph_ipv4hdr_t *ip; - odph_udphdr_t *udp; odph_icmphdr_t *icmp; struct timeval tvrecv; struct timeval tvsend; @@ -507,20 +488,13 @@ static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) continue; odp_atomic_inc_u64(&counters.ip); - rlen += sprintf(msg, "receive Packet proto:IP "); buf = odp_packet_data(pkt); ip = (odph_ipv4hdr_t *)(buf + odp_packet_l3_offset(pkt)); - rlen += sprintf(msg + rlen, "id %d ", - odp_be_to_cpu_16(ip->id)); offset = odp_packet_l4_offset(pkt); /* udp */ if (ip->proto == ODPH_IPPROTO_UDP) { odp_atomic_inc_u64(&counters.udp); - udp = (odph_udphdr_t *)(buf + offset); - rlen += sprintf(msg + rlen, "UDP payload %d ", - odp_be_to_cpu_16(udp->length) - - ODPH_UDPHDR_LEN); } /* icmp */ @@ -544,10 +518,10 @@ static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) rlen += sprintf(msg + rlen, "Icmp Echo Request"); } - } - msg[rlen] = '\0'; - printf(" [%02i] %s\n", thr, msg); + msg[rlen] = '\0'; + printf(" [%02i] %s\n", thr, msg); + } } } @@ -577,6 +551,12 @@ static void *gen_recv_thread(void *arg) printf(" [%02i] created mode: RECEIVE\n", thr); for (;;) { + if (args->appl.number != -1 && + odp_atomic_load_u64(&counters.icmp) >= + (unsigned int)args->appl.number) { + break; + } + /* Use schedule to get buf from any input queue */ ev = odp_schedule(NULL, ODP_SCHED_WAIT); @@ -594,6 +574,64 @@ static void *gen_recv_thread(void *arg) return arg; } + +/** + * printing verbose statistics + * + */ +static void print_global_stats(int num_workers) +{ + uint64_t start, now, diff; + uint64_t pkts, pkts_prev = 0, pps, maximum_pps = 0; + int verbose_interval = 20; + odp_thrmask_t thrd_mask; + + while (odp_thrmask_worker(&thrd_mask) < num_workers) + continue; + + start = odp_time_cycles(); + + while (odp_thrmask_worker(&thrd_mask) == num_workers) { + if (args->appl.number != -1 && + odp_atomic_load_u64(&counters.seq) >= + (unsigned int)args->appl.number) { + break; + } + + now = odp_time_cycles(); + diff = odp_time_diff_cycles(start, now); + if (odp_time_cycles_to_ns(diff) < + verbose_interval * ODP_TIME_SEC) { + continue; + } + + start = odp_time_cycles(); + + if (args->appl.mode == APPL_MODE_RCV) { + pkts = odp_atomic_load_u64(&counters.udp); + printf(" total receive(UDP: %" PRIu64 ")\n", pkts); + continue; + } + + if (args->appl.mode == APPL_MODE_PING) { + pkts = odp_atomic_load_u64(&counters.icmp); + printf(" total receive(ICMP: %" PRIu64 ")\n", pkts); + } + + pkts = odp_atomic_load_u64(&counters.seq); + printf(" total sent: %" PRIu64 "\n", pkts); + + if (args->appl.mode == APPL_MODE_UDP) { + pps = (pkts - pkts_prev) / verbose_interval; + if (pps > maximum_pps) + maximum_pps = pps; + printf(" %" PRIu64 " pps, %" PRIu64 " max pps\n", + pps, maximum_pps); + pkts_prev = pkts; + } + } +} + /** * ODP packet example main function */ @@ -650,18 +688,28 @@ int main(int argc, char *argv[]) if (args->appl.cpu_count) num_workers = args->appl.cpu_count; - /* ping mode need two worker */ - if (args->appl.mode == APPL_MODE_PING) - num_workers = 2; - - /* Get default worker cpumask */ num_workers = odp_cpumask_def_worker(&cpumask, num_workers); + if (args->appl.mask) { + odp_cpumask_from_str(&cpumask, args->appl.mask); + num_workers = odp_cpumask_count(&cpumask); + } + (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr)); printf("num worker threads: %i\n", num_workers); printf("first CPU: %i\n", odp_cpumask_first(&cpumask)); printf("cpu mask: %s\n", cpumaskstr); + /* ping mode need two workers */ + if (args->appl.mode == APPL_MODE_PING) { + if (num_workers < 2) { + EXAMPLE_ERR("Need at least two worker threads\n"); + exit(EXIT_FAILURE); + } else { + num_workers = 2; + } + } + /* Create packet pool */ odp_pool_param_init(¶ms); params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE; @@ -709,12 +757,13 @@ int main(int argc, char *argv[]) memset(thread_tbl, 0, sizeof(thread_tbl)); if (args->appl.mode == APPL_MODE_PING) { - odp_cpumask_t cpu0_mask; + odp_cpumask_t cpu_mask; odp_queue_t tq; + int cpu_first, cpu_next; - /* Previous code forced both threads to CPU 0 */ - odp_cpumask_zero(&cpu0_mask); - odp_cpumask_set(&cpu0_mask, 0); + odp_cpumask_zero(&cpu_mask); + cpu_first = odp_cpumask_first(&cpumask); + odp_cpumask_set(&cpu_mask, cpu_first); tq = odp_queue_create("", ODP_QUEUE_TYPE_POLL, NULL); if (tq == ODP_QUEUE_INVALID) @@ -730,7 +779,7 @@ int main(int argc, char *argv[]) if (args->thread[1].tmo_ev == ODP_TIMEOUT_INVALID) abort(); args->thread[1].mode = args->appl.mode; - odph_linux_pthread_create(&thread_tbl[1], &cpu0_mask, + odph_linux_pthread_create(&thread_tbl[1], &cpu_mask, gen_recv_thread, &args->thread[1]); tq = odp_queue_create("", ODP_QUEUE_TYPE_POLL, NULL); @@ -747,11 +796,12 @@ int main(int argc, char *argv[]) if (args->thread[0].tmo_ev == ODP_TIMEOUT_INVALID) abort(); args->thread[0].mode = args->appl.mode; - odph_linux_pthread_create(&thread_tbl[0], &cpu0_mask, + cpu_next = odp_cpumask_next(&cpumask, cpu_first); + odp_cpumask_zero(&cpu_mask); + odp_cpumask_set(&cpu_mask, cpu_next); + odph_linux_pthread_create(&thread_tbl[0], &cpu_mask, gen_send_thread, &args->thread[0]); - /* only wait send thread to join */ - num_workers = 1; } else { int cpu = odp_cpumask_first(&cpumask); for (i = 0; i < num_workers; ++i) { @@ -801,6 +851,8 @@ int main(int argc, char *argv[]) } } + print_global_stats(num_workers); + /* Master thread waits for other threads to exit */ odph_linux_pthread_join(thread_tbl, num_workers); @@ -825,15 +877,17 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) int long_index; char *token; size_t len; - int i; + odp_cpumask_t cpumask, cpumask_args, cpumask_and; + int i, num_workers; static struct option longopts[] = { {"interface", required_argument, NULL, 'I'}, {"workers", required_argument, NULL, 'w'}, + {"cpumask", required_argument, NULL, 'c'}, {"srcmac", required_argument, NULL, 'a'}, {"dstmac", required_argument, NULL, 'b'}, - {"srcip", required_argument, NULL, 'c'}, + {"srcip", required_argument, NULL, 's'}, {"dstip", required_argument, NULL, 'd'}, - {"packetsize", required_argument, NULL, 's'}, + {"packetsize", required_argument, NULL, 'p'}, {"mode", required_argument, NULL, 'm'}, {"count", required_argument, NULL, 'n'}, {"timeout", required_argument, NULL, 't'}, @@ -848,8 +902,8 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) appl_args->timeout = -1; while (1) { - opt = getopt_long(argc, argv, "+I:a:b:c:d:s:i:m:n:t:w:h", - longopts, &long_index); + opt = getopt_long(argc, argv, "+I:a:b:s:d:p:i:m:n:t:w:c:h", + longopts, &long_index); if (opt == -1) break; /* No more options */ @@ -857,6 +911,18 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) case 'w': appl_args->cpu_count = atoi(optarg); break; + case 'c': + appl_args->mask = optarg; + odp_cpumask_from_str(&cpumask_args, args->appl.mask); + num_workers = odp_cpumask_def_worker(&cpumask, 0); + odp_cpumask_and(&cpumask_and, &cpumask_args, &cpumask); + if (odp_cpumask_count(&cpumask_and) < + odp_cpumask_count(&cpumask_args)) { + EXAMPLE_ERR("Wrong cpu mask, max cpu's:%d\n", + num_workers); + exit(EXIT_FAILURE); + } + break; /* parse packet-io interface names */ case 'I': len = strlen(optarg); @@ -925,7 +991,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) } break; - case 'c': + case 's': if (scan_ip(optarg, &appl_args->srcip) != 1) { EXAMPLE_ERR("wrong src ip:%s\n", optarg); exit(EXIT_FAILURE); @@ -939,7 +1005,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) } break; - case 's': + case 'p': appl_args->payload = atoi(optarg); break; @@ -1032,26 +1098,29 @@ static void usage(char *progname) " 2.receive udp packets\n" " odp_generator -I eth0 -m r\n" " 3.work likes ping\n" - " odp_generator -I eth0 --srcmac fe:0f:97:c9:e0:44 --dstmac 32:cb:9b:27:2f:1a --srcip 192.168.0.1 --dstip 192.168.0.2 -m p\n" + " odp_generator -I eth0 --srcmac fe:0f:97:c9:e0:44 --dstmac 32:cb:9b:27:2f:1a --srcip 192.168.0.1 --dstip 192.168.0.2 --cpumask 0xc -m p\n" "\n" "Mandatory OPTIONS:\n" " -I, --interface Eth interfaces (comma-separated, no spaces)\n" " -a, --srcmac src mac address\n" " -b, --dstmac dst mac address\n" - " -c, --srcip src ip address\n" + " -s, --srcip src ip address\n" " -d, --dstip dst ip address\n" - " -s, --packetsize payload length of the packets\n" " -m, --mode work mode: send udp(u), receive(r), send icmp(p)\n" - " -n, --count the number of packets to be send\n" - " -t, --timeout only for ping mode, wait ICMP reply timeout seconds\n" - " -i, --interval wait interval ms between sending each packet\n" - " default is 1000ms. 0 for flood mode\n" "\n" "Optional OPTIONS\n" " -h, --help Display help and exit.\n" " environment variables: ODP_PKTIO_DISABLE_SOCKET_MMAP\n" " ODP_PKTIO_DISABLE_SOCKET_MMSG\n" " can be used to advanced pkt I/O selection for linux-generic\n" + " -p, --packetsize payload length of the packets\n" + " -t, --timeout only for ping mode, wait ICMP reply timeout seconds\n" + " -i, --interval wait interval ms between sending each packet\n" + " default is 1000ms. 0 for flood mode\n" + " -w, --workers specify number of workers need to be assigned to application\n" + " default is to assign all\n" + " -n, --count the number of packets to be send\n" + " -c, --cpumask to set on cores\n" "\n", NO_PATH(progname), NO_PATH(progname) ); } |