1 // SPDX-License-Identifier: GPL-2.0
3 * This times how long it takes to bind to a port when the port already
4 * has multiple sockets in its bhash table.
6 * In the setup(), we populate the port's bhash table with
7 * MAX_THREADS * MAX_CONNECTIONS number of entries.
15 #define MAX_THREADS 600
16 #define MAX_CONNECTIONS 40
18 static const char *bind_addr = "::1";
19 static const char *port;
21 static int fd_array[MAX_THREADS][MAX_CONNECTIONS];
23 static int bind_socket(int opt, const char *addr)
25 struct addrinfo *res, hint = {};
26 int sock_fd, reuse = 1, err;
28 sock_fd = socket(AF_INET6, SOCK_STREAM, 0);
30 perror("socket fd err");
34 hint.ai_family = AF_INET6;
35 hint.ai_socktype = SOCK_STREAM;
37 err = getaddrinfo(addr, port, &hint, &res);
39 perror("getaddrinfo failed");
44 err = setsockopt(sock_fd, SOL_SOCKET, opt, &reuse, sizeof(reuse));
46 perror("setsockopt failed");
51 err = bind(sock_fd, res->ai_addr, res->ai_addrlen);
53 perror("failed to bind to port");
60 static void *setup(void *arg)
63 int *array = (int *)arg;
65 for (i = 0; i < MAX_CONNECTIONS; i++) {
66 sock_fd = bind_socket(SO_REUSEADDR | SO_REUSEPORT, bind_addr);
75 int main(int argc, const char *argv[])
77 int listener_fd, sock_fd, i, j;
78 pthread_t tid[MAX_THREADS];
82 printf("Usage: listener <port>\n");
88 listener_fd = bind_socket(SO_REUSEADDR | SO_REUSEPORT, bind_addr);
89 if (listen(listener_fd, 100) < 0) {
90 perror("listen failed");
94 /* Set up threads to populate the bhash table entry for the port */
95 for (i = 0; i < MAX_THREADS; i++)
96 pthread_create(&tid[i], NULL, setup, fd_array[i]);
98 for (i = 0; i < MAX_THREADS; i++)
99 pthread_join(tid[i], NULL);
103 /* Bind to the same port on a different address */
104 sock_fd = bind_socket(0, "2001:0db8:0:f101::1");
108 printf("time spent = %f\n", (double)(end - begin) / CLOCKS_PER_SEC);
113 for (i = 0; i < MAX_THREADS; i++) {
114 for (j = 0; i < MAX_THREADS; i++)
115 close(fd_array[i][j]);