tools/netrate: Get socket's cpu hint and bind cpu accordingly
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 28 Sep 2014 11:43:20 +0000 (19:43 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 28 Sep 2014 12:49:12 +0000 (20:49 +0800)
tools/tools/netrate/accept_connect/kq_accept_server/kq_accept_server.c
tools/tools/netrate/udpecho/udpecho.c

index e4d17d7..8ab4fa8 100644 (file)
@@ -4,6 +4,7 @@
 #include <sys/socket.h>
 #include <sys/sysctl.h>
 #include <sys/time.h>
+#include <sys/usched.h>
 
 #include <arpa/inet.h>
 #include <netinet/in.h>
 
 #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");
index a6e1fea..bdcc1e9 100644 (file)
@@ -1,6 +1,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/sysctl.h>
+#include <sys/usched.h>
 
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #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);
                }