From 050d2368c689a5f79c2dc32bd2dc202d9ba724e9 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Sun, 28 Sep 2014 19:43:20 +0800 Subject: [PATCH] tools/netrate: Get socket's cpu hint and bind cpu accordingly --- .../kq_accept_server/kq_accept_server.c | 34 +++++++++++---- tools/tools/netrate/udpecho/udpecho.c | 41 ++++++++++++++----- 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/tools/tools/netrate/accept_connect/kq_accept_server/kq_accept_server.c b/tools/tools/netrate/accept_connect/kq_accept_server/kq_accept_server.c index e4d17d771b..8ab4fa8346 100644 --- a/tools/tools/netrate/accept_connect/kq_accept_server/kq_accept_server.c +++ b/tools/tools/netrate/accept_connect/kq_accept_server/kq_accept_server.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -16,12 +17,12 @@ #define EVENT_MAX 128 -static void mainloop(int, const struct sockaddr_in *); +static void mainloop(int, const struct sockaddr_in *, int); static void usage(const char *cmd) { - fprintf(stderr, "%s -p port [-i n_instance] [-r]\n", cmd); + fprintf(stderr, "%s -p port [-i n_instance] [-r] [-B]\n", cmd); exit(1); } @@ -61,7 +62,7 @@ int main(int argc, char *argv[]) { struct sockaddr_in in; - int opt, ninst, serv_s, i, reuseport; + int opt, ninst, serv_s, i, reuseport, bindcpu; size_t prm_len; prm_len = sizeof(ninst); @@ -72,9 +73,10 @@ main(int argc, char *argv[]) in.sin_family = AF_INET; in.sin_addr.s_addr = INADDR_ANY; + bindcpu = 0; reuseport = 0; - while ((opt = getopt(argc, argv, "p:i:r")) != -1) { + while ((opt = getopt(argc, argv, "Bp:i:r")) != -1) { switch (opt) { case 'p': in.sin_port = htons(atoi(optarg)); @@ -88,6 +90,10 @@ main(int argc, char *argv[]) reuseport = 1; break; + case 'B': + bindcpu = 1; + break; + default: usage(argv[0]); } @@ -95,6 +101,8 @@ main(int argc, char *argv[]) if (ninst < 1 || in.sin_port == 0) usage(argv[0]); + if (!reuseport) + bindcpu = 0; serv_s = -1; if (!reuseport) @@ -105,19 +113,19 @@ main(int argc, char *argv[]) pid = fork(); if (pid == 0) { - mainloop(serv_s, &in); + mainloop(serv_s, &in, bindcpu); exit(0); } else if (pid < 0) { err(1, "fork failed"); } } - mainloop(serv_s, &in); + mainloop(serv_s, &in, bindcpu); exit(0); } static void -mainloop(int serv_s, const struct sockaddr_in *in) +mainloop(int serv_s, const struct sockaddr_in *in, int bindcpu) { struct kevent change_evt0[EVENT_MAX]; int kq, nchange; @@ -125,6 +133,18 @@ mainloop(int serv_s, const struct sockaddr_in *in) if (serv_s < 0) serv_s = create_socket(in, 1); + if (bindcpu) { + socklen_t cpu_len; + int cpu; + + cpu_len = sizeof(cpu); + if (getsockopt(serv_s, SOL_SOCKET, SO_CPUHINT, + &cpu, &cpu_len) < 0) + err(1, "getsockopt(CPUHINT) failed"); + if (cpu >= 0) + usched_set(getpid(), USCHED_SET_CPU, &cpu, sizeof(cpu)); + } + kq = kqueue(); if (kq < 0) err(1, "kqueue failed"); diff --git a/tools/tools/netrate/udpecho/udpecho.c b/tools/tools/netrate/udpecho/udpecho.c index a6e1fea1f2..bdcc1e901c 100644 --- a/tools/tools/netrate/udpecho/udpecho.c +++ b/tools/tools/netrate/udpecho/udpecho.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -15,13 +16,16 @@ #define RCVBUF_SIZE (256 * 1024) #define BUFLEN 2048 -static void mainloop(struct sockaddr_in *, int, int, int); +#define FLAG_NOREPLY 0x0001 +#define FLAG_BINDCPU 0x0002 + +static void mainloop(struct sockaddr_in *, int, int, uint32_t); static void usage(const char *cmd) { - fprintf(stderr, "%s -4 addr4 -p port [-i ninst] [-r rcvbuf] [-N]\n", - cmd); + fprintf(stderr, "%s -4 addr4 -p port [-i ninst] [-r rcvbuf] " + "[-N] [-B]\n", cmd); exit(2); } @@ -29,7 +33,7 @@ int main(int argc, char *argv[]) { struct sockaddr_in in; - int opt, ninst, i, s, rcvbuf, noreply; + int opt, ninst, i, s, rcvbuf, flags; size_t prm_len; prm_len = sizeof(ninst); @@ -39,10 +43,10 @@ main(int argc, char *argv[]) memset(&in, 0, sizeof(in)); in.sin_family = AF_INET; - noreply = 0; + flags = 0; rcvbuf = RCVBUF_SIZE; - while ((opt = getopt(argc, argv, "4:p:i:r:N")) != -1) { + while ((opt = getopt(argc, argv, "4:p:i:r:NB")) != -1) { switch (opt) { case '4': if (inet_pton(AF_INET, optarg, &in.sin_addr) <= 0) @@ -64,7 +68,11 @@ main(int argc, char *argv[]) break; case 'N': - noreply = 1; + flags |= FLAG_NOREPLY; + break; + + case 'B': + flags |= FLAG_BINDCPU; break; default: @@ -82,17 +90,17 @@ main(int argc, char *argv[]) pid = fork(); if (pid == 0) - mainloop(&in, s, rcvbuf, noreply); + mainloop(&in, s, rcvbuf, flags); else if (pid < 0) err(1, "fork %d failed", i); } - mainloop(&in, s, rcvbuf, noreply); + mainloop(&in, s, rcvbuf, flags); exit(0); } static void -mainloop(struct sockaddr_in *in, int s, int rcvbuf, int noreply) +mainloop(struct sockaddr_in *in, int s, int rcvbuf, uint32_t flags) { int on; void *buf; @@ -117,6 +125,17 @@ mainloop(struct sockaddr_in *in, int s, int rcvbuf, int noreply) if (bind(s, (const struct sockaddr *)in, sizeof(*in)) < 0) err(1, "bind failed"); + if (flags & FLAG_BINDCPU) { + socklen_t cpu_len; + int cpu; + + cpu_len = sizeof(cpu); + if (getsockopt(s, SOL_SOCKET, SO_CPUHINT, &cpu, &cpu_len) < 0) + err(1, "getsockopt(SOCK, CPUHINT) failed"); + if (cpu >= 0) + usched_set(getpid(), USCHED_SET_CPU, &cpu, sizeof(cpu)); + } + for (;;) { struct sockaddr_in cli; socklen_t cli_len; @@ -125,7 +144,7 @@ mainloop(struct sockaddr_in *in, int s, int rcvbuf, int noreply) cli_len = sizeof(cli); n = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&cli, &cli_len); - if (n > 0 && !noreply) { + if (n > 0 && (flags & FLAG_NOREPLY) == 0) { sendto(s, buf, n, 0, (const struct sockaddr *)&cli, cli_len); } -- 2.41.0