]> git.feebdaed.xyz Git - linuxyz.git/commitdiff
done select poll epoll bench
authorseantywork <seantywork@gmail.com>
Sun, 18 May 2025 04:58:58 +0000 (04:58 +0000)
committerseantywork <seantywork@gmail.com>
Sun, 18 May 2025 04:58:58 +0000 (04:58 +0000)
12 files changed:
iperf/2505-03.xyz.md [deleted file]
iperf/Makefile [deleted file]
iperf/iperf_s.c [deleted file]
iperf/iperf_s.h [deleted file]
iperf/main.c [deleted file]
iperf/setup.sh [deleted file]
ten-k/2505-03.xyz.md [new file with mode: 0644]
ten-k/Makefile [new file with mode: 0644]
ten-k/main.c [new file with mode: 0644]
ten-k/setup.sh [new file with mode: 0755]
ten-k/tenk.c [new file with mode: 0644]
ten-k/tenk.h [new file with mode: 0644]

diff --git a/iperf/2505-03.xyz.md b/iperf/2505-03.xyz.md
deleted file mode 100644 (file)
index 99e5f82..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-# 
-
-```shell
-
-
-sudo ip netns exec net1 iperf3 -s -p 5001
------------------------------------------------------------
-Server listening on 5001 (test #1)
------------------------------------------------------------
-
-```
-
-#
-
-```shell
-iperf$ sudo iperf3 -c 192.168.62.6 -p 5001 -t 60 -i 
-1
-Connecting to host 192.168.62.6, port 5001
-[  5] local 192.168.62.5 port 41342 connected to 192.168.62.6 port 5001
-[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
-[  5]   0.00-1.00   sec  4.91 GBytes  42.2 Gbits/sec    0    478 KBytes       
-[  5]   1.00-2.00   sec  5.00 GBytes  42.9 Gbits/sec    0    600 KBytes       
-[  5]   2.00-3.00   sec  5.06 GBytes  43.5 Gbits/sec    0    600 KBytes       
-[  5]   3.00-4.00   sec  5.03 GBytes  43.2 Gbits/sec    0    600 KBytes       
-^C[  5]   4.00-4.53   sec  2.67 GBytes  43.6 Gbits/sec    0    600 KBytes       
-- - - - - - - - - - - - - - - - - - - - - - - - -
-[ ID] Interval           Transfer     Bitrate         Retr
-[  5]   0.00-4.53   sec  22.8 GBytes  43.2 Gbits/sec    0             sender
-[  5]   0.00-4.53   sec  0.00 Bytes  0.00 bits/sec                  receiver
-iperf3: interrupt - the client has terminated
-
-```
-
-```shell
-
-Accepted connection from 192.168.62.5, port 41336
-[  5] local 192.168.62.6 port 5001 connected to 192.168.62.5 port 41342
-[ ID] Interval           Transfer     Bitrate
-[  5]   0.00-1.00   sec  4.91 GBytes  42.2 Gbits/sec                  
-[  5]   1.00-2.00   sec  5.02 GBytes  43.1 Gbits/sec                  
-[  5]   2.00-3.00   sec  5.08 GBytes  43.7 Gbits/sec                  
-[  5]   3.00-4.00   sec  5.06 GBytes  43.4 Gbits/sec                  
-[  5]   3.00-4.00   sec  5.06 GBytes  43.4 Gbits/sec                  
-- - - - - - - - - - - - - - - - - - - - - - - - -
-[ ID] Interval           Transfer     Bitrate
-[  5]   0.00-4.00   sec  22.8 GBytes  48.9 Gbits/sec                  receiver
-iperf3: the client has terminated
------------------------------------------------------------
-Server listening on 5001 (test #2)
------------------------------------------------------------
-
-```
-
-
-# 
-
-```shell
-
-192.168.62.5 -> 192.168.62.6
-41440 -> 9999
-
-0000  68 68 77 68 72 33 66 73 68 36 33 70 36 7a 65 63   hhwhr3fsh63p6zec
-0010  74 76 79 71 6c 6f 66 36 6b 77 6e 6f 6c 36 70 6f   tvyqlof6kwnol6po
-0020  6e 7a 75 70 00                                    nzup.
-
-
-
-```
-
-#
-
-```shell
-192.168.62.6 -> 192.168.62.5
-9999 -> 41440
-
-    TCP payload (1 byte)
-Data (1 byte)
-
-0000  09                                                .
-    Data: 09
-    [Length: 1]
-
-
-```
-
-# 
-
-```shell
-
-192.168.62.5 -> 192.168.62.6
-41440 -> 9999
-
-Data (4 bytes)
-
-0000  00 00 00 7c                                       ...|
-    Data: 0000007c
-    [Length: 4]
-
-
-
-```
-
-```shell
-
-192.168.62.5 -> 192.168.62.6
-41440 -> 9999
-
-    TCP payload (124 bytes)
-Data (124 bytes)
-
-0000  7b 22 74 63 70 22 3a 74 72 75 65 2c 22 6f 6d 69   {"tcp":true,"omi
-0010  74 22 3a 30 2c 22 74 69 6d 65 22 3a 31 30 2c 22   t":0,"time":10,"
-0020  6e 75 6d 22 3a 30 2c 22 62 6c 6f 63 6b 63 6f 75   num":0,"blockcou
-0030  6e 74 22 3a 30 2c 22 70 61 72 61 6c 6c 65 6c 22   nt":0,"parallel"
-0040  3a 31 2c 22 6c 65 6e 22 3a 31 33 31 30 37 32 2c   :1,"len":131072,
-0050  22 70 61 63 69 6e 67 5f 74 69 6d 65 72 22 3a 31   "pacing_timer":1
-0060  30 30 30 2c 22 63 6c 69 65 6e 74 5f 76 65 72 73   000,"client_vers
-0070  69 6f 6e 22 3a 22 33 2e 31 36 22 7d               ion":"3.16"}
-
-
-
-```
-
-# 
-
-```shell
-
-192.168.62.6 -> 192.168.62.5
-9999 -> 41440
-
-    TCP payload (1 byte)
-Data (1 byte)
-
-0000  0a                                                .
-    Data: 0a
-    [Length: 1]
-
-```
-
-#
-
-```shell
-
-
-192.168.62.5 -> 192.168.62.6
-41448 -> 9999
-
-    TCP payload (37 bytes)
-Data (37 bytes)
-
-0000  68 68 77 68 72 33 66 73 68 36 33 70 36 7a 65 63   hhwhr3fsh63p6zec
-0010  74 76 79 71 6c 6f 66 36 6b 77 6e 6f 6c 36 70 6f   tvyqlof6kwnol6po
-0020  6e 7a 75 70 00                                    nzup.
-
-```
-
-#
-
-```shell
-
-192.168.62.6 -> 192.168.62.5
-9999 -> 41440
-
-    TCP payload (1 byte)
-Data (1 byte)
-
-0000  01                                                .
-    Data: 01
-    [Length: 1]
-```
-
-```shell
-
-192.168.62.6 -> 192.168.62.5
-9999 -> 41440
-
-
-    TCP payload (1 byte)
-Data (1 byte)
-
-0000  02                                                .
-    Data: 02
-    [Length: 1]
-
-
-```
-
-#
-
-```shell
-
-192.168.62.5 -> 192.168.62.6
-41448 -> 9999
-
-    TCP payload (7240 bytes)
-Data (7240 bytes)
-
-0000  55 7c 4c 02 5e 17 5c bc 5b da b6 c0 6f 5d f6 d7   U|L.^.\.[...o]..
-0010  c5 df 58 8d e3 e1 5c cc a8 26 ce c0 77 08 e7 8b   ..X...\..&..w...
-0020  c3 bc 5d 60 bc 19 6b 6b 94 f1 f3 e8 ae f3 fd b4   ..]`..kk........
-0030  2b b9 2f ca 77 2b 43 15 62 56 eb 13 ff b0 c7 82   +./.w+C.bV......
-0040  b9 6e 78 a1 3c 2d 90 6e b8 48 73 f8 8e d8 5c 20   .nx.<-.n.Hs...\ 
-
-```
-
-
-# 
-
-
-```shell
-
-Data (1 byte)
-    Data: 0d
-    [Length: 1]
-
-
-```
-
-# 
-
-```shell
-
-Frame 55388: 70 bytes on wire (560 bits), 70 bytes captured (560 bits) on interface veth11, id 0
-Ethernet II, Src: 82:c8:ff:58:e7:e7 (82:c8:ff:58:e7:e7), Dst: 46:5f:bb:78:a9:5e (46:5f:bb:78:a9:5e)
-Internet Protocol Version 4, Src: 192.168.62.5, Dst: 192.168.62.6
-Transmission Control Protocol, Src Port: 33886, Dst Port: 9999, Seq: 166, Ack: 6, Len: 4
-Data (4 bytes)
-    Data: 00000145
-    [Length: 4]
-
-
-```
-
-```shell
-
-0000   46 5f bb 78 a9 5e 82 c8 ff 58 e7 e7 08 00 45 00   F_.x.^...X....E.
-0010   01 79 14 2c 40 00 40 06 27 f7 c0 a8 3e 05 c0 a8   .y.,@.@.'...>...
-0020   3e 06 84 5e 27 0f 99 98 11 ab 94 a1 6d 1f 80 18   >..^'.......m...
-0030   01 f6 fe c7 00 00 01 01 08 0a 9d eb 12 cb f2 7d   ...............}
-0040   0e eb 7b 22 63 70 75 5f 75 74 69 6c 5f 74 6f 74   ..{"cpu_util_tot
-0050   61 6c 22 3a 39 39 2e 38 39 31 31 32 35 35 39 32   al":99.891125592
-0060   33 34 36 33 37 2c 22 63 70 75 5f 75 74 69 6c 5f   34637,"cpu_util_
-0070   75 73 65 72 22 3a 31 2e 31 39 33 33 34 33 30 35   user":1.19334305
-0080   30 38 32 39 39 33 31 32 2c 22 63 70 75 5f 75 74   08299312,"cpu_ut
-0090   69 6c 5f 73 79 73 74 65 6d 22 3a 39 38 2e 36 39   il_system":98.69
-00a0   37 37 38 32 35 34 31 35 31 36 34 34 36 2c 22 73   7782541516446,"s
-00b0   65 6e 64 65 72 5f 68 61 73 5f 72 65 74 72 61 6e   ender_has_retran
-00c0   73 6d 69 74 73 22 3a 31 2c 22 63 6f 6e 67 65 73   smits":1,"conges
-00d0   74 69 6f 6e 5f 75 73 65 64 22 3a 22 63 75 62 69   tion_used":"cubi
-00e0   63 22 2c 22 73 74 72 65 61 6d 73 22 3a 5b 7b 22   c","streams":[{"
-00f0   69 64 22 3a 31 2c 22 62 79 74 65 73 22 3a 37 36   id":1,"bytes":76
-0100   39 38 39 30 37 31 33 36 2c 22 72 65 74 72 61 6e   98907136,"retran
-0110   73 6d 69 74 73 22 3a 30 2c 22 6a 69 74 74 65 72   smits":0,"jitter
-0120   22 3a 30 2c 22 65 72 72 6f 72 73 22 3a 30 2c 22   ":0,"errors":0,"
-0130   6f 6d 69 74 74 65 64 5f 65 72 72 6f 72 73 22 3a   omitted_errors":
-0140   30 2c 22 70 61 63 6b 65 74 73 22 3a 30 2c 22 6f   0,"packets":0,"o
-0150   6d 69 74 74 65 64 5f 70 61 63 6b 65 74 73 22 3a   mitted_packets":
-0160   30 2c 22 73 74 61 72 74 5f 74 69 6d 65 22 3a 30   0,"start_time":0
-0170   2c 22 65 6e 64 5f 74 69 6d 65 22 3a 31 2e 30 30   ,"end_time":1.00
-0180   35 31 33 33 7d 5d 7d                              5133}]}
-
-
-```
-
-
-#
-
-```shell
-
-
-Data (1 byte)
-    Data: 0e
-    [Length: 1]
-
-```
-
-
-#
-
-```c
-
-static uint8_t ctl_hello[37] = {0};
-static uint8_t ctl_hellow_answer[1] = {0x09};
-static uint32_t ctl_info_size = 0;
-static uint8_t* ctl_info = NULL;
-static uint8_t ctl_info_answer[1] = {0x0a};
-static uint8_t ctl_start_1[1] = {0x01};
-static uint8_t ctl_start_2[1] = {0x02};
-static uint8_t ctl_end_1[1] = {0x0d};
-static uint8_t ctl_end_2[1] = {0x0e};
-
-```
-
-# 
-
-```c
-
-
-
-```
\ No newline at end of file
diff --git a/iperf/Makefile b/iperf/Makefile
deleted file mode 100644 (file)
index ab7f41e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-GCC_FLAGS := -Wall -O2 -g
-
-all: iperf_s.o
-
-       gcc $(GCC_FLAGS) -I. -o iperf_s.out main.c iperf_s.o -lpthread
-
-
-iperf_s.o: 
-
-       gcc $(GCC_FLAGS) -c -I. -o iperf_s.o iperf_s.c
-
-clean:
-       rm -r *.o *.a *.so *.out
\ No newline at end of file
diff --git a/iperf/iperf_s.c b/iperf/iperf_s.c
deleted file mode 100644 (file)
index 888c083..0000000
+++ /dev/null
@@ -1,475 +0,0 @@
-#include "iperf_s.h"
-
-
-static uint8_t ctl_hello[37] = {0};
-static uint8_t ctl_hellow_answer[1] = {0x09};
-static uint32_t ctl_info_size = 0;
-static uint8_t* ctl_info = NULL;
-static uint8_t ctl_info_answer[1] = {0x0a};
-static uint8_t ctl_start_1[1] = {0x01};
-static uint8_t ctl_start_2[1] = {0x02};
-static uint8_t ctl_end_1[1] = {0x0d};
-static uint8_t ctl_end_2[1] = {0x0e};
-
-static uint8_t hello[37] = {0};
-
-int make_socket_non_blocking(int sfd){
-    int flags, s;
-  
-    flags = fcntl (sfd, F_GETFL, 0);
-    if (flags == -1){
-        printf("fcntl get");
-        return -1;
-    }
-  
-    flags |= O_NONBLOCK;
-    s = fcntl (sfd, F_SETFL, flags);
-    if (s == -1){
-        printf("fcntl set");
-        return -2;
-    } 
-    return 0;
-}
-
-void* ctl_thread(void* varg){
-
-    pthread_mutex_unlock(&lock);
-    sleep(timeout);
-    write(ctl_fd, ctl_end_1, 1);
-    read(ctl_fd, &ctl_info_size, 4);
-    uint32_t isize = ntohl(ctl_info_size);
-    ctl_info = (uint8_t*)malloc(isize * sizeof(uint8_t));
-    read(ctl_fd, ctl_info, isize);
-    printf("%s\n",ctl_info);
-    write(ctl_fd, &ctl_info_size, 4);
-    write(ctl_fd, ctl_info, isize);
-    write(ctl_fd, ctl_end_2, 1);
-    free(ctl_info);
-    
-    //close(ctl_fd);
-
-    pthread_exit(NULL);
-
-}
-
-void ctl_runner(){
-
-
-    pthread_t tid;
-
-    pthread_mutex_lock(&lock);
-
-    read(ctl_fd, ctl_hello, 37);
-    write(ctl_fd, ctl_hellow_answer, 1);
-    read(ctl_fd, &ctl_info_size, 4);
-
-    uint32_t isize = ntohl(ctl_info_size);
-    ctl_info = (uint8_t*)malloc(isize * sizeof(uint8_t));
-    read(ctl_fd, ctl_info, isize);
-    write(ctl_fd, ctl_info_answer, 1);
-
-    pthread_create(&tid, NULL, ctl_thread, NULL);
-
-    free(ctl_info);
-
-}
-
-int run_select(int fd, struct sockaddr_in* servaddr){
-
-    int connections = 0;
-
-    int max_fd = 0;
-    int event = 0;
-    fd_set readfds;
-    int servlen;
-    int client_fds[MAXCLIENT] = {0};
-    int valread;
-    int n;
-    int client_fd;
-
-    int keep = 1;
-
-    servlen = sizeof(*servaddr);   
-    
-    while(keep){
-
-        FD_ZERO(&readfds);
-        FD_SET(fd, &readfds);
-        max_fd = fd;
-
-        for(int i = 0; i < client_num; i++){
-            client_fd = client_fds[i];
-
-            if(client_fd > 0){
-                FD_SET(client_fd, &readfds);
-            }
-            if(client_fd > max_fd){
-                max_fd = client_fd;
-            }
-            
-        }
-
-        event = select(max_fd + 1, &readfds, NULL, NULL, NULL);
-
-        if ((event < 0 ) && (errno != EINTR)){
-            printf("select error\n");
-            break;
-        }
-
-        do {
-            if(FD_ISSET(fd, &readfds)){
-                int added = 0;
-                event -= 1;
-                client_fd = accept(fd, (struct sockaddr*)servaddr, (socklen_t*)&servlen);
-
-                if(client_fd < 0){
-                    printf("failed to accept\n");
-                    break;
-                }
-
-                if(ctl_fd == 0){
-
-                    ctl_fd = client_fd;
-
-                    ctl_runner(ctl_fd);
-
-                    break;
-
-                } else {
-
-                    read(client_fd, hello, 37);
-                    connections += 1;
-
-                    if(connections == client_num){
-                        pthread_mutex_lock(&lock);
-                        write(ctl_fd, ctl_start_1, 1);
-                        write(ctl_fd, ctl_start_2, 1);
-                        pthread_mutex_unlock(&lock);
-                    }
-
-                }
-
-                if(make_socket_non_blocking(client_fd) < 0){
-                    printf("accept non-blocking failed\n");
-                    break;
-                }
-                for(int i = 0; i < client_num; i++){
-                    if(client_fds[i] == 0){
-                        client_fds[i] = client_fd;
-                        added = 1;
-                        break;
-                    }
-                }
-                if(added != 1){
-                    printf("accept slot full\n");
-                    break;
-                }
-
-            }
-        } while(0);
-
-        for(int i = 0; i < client_num; i++){
-            if(event == 0){
-                break;
-            }
-            client_fd = client_fds[i];
-            if(client_fd == 0){
-                continue;
-            }
-            if(FD_ISSET(client_fd, &readfds)){
-                valread = 0;
-                n = 0;
-                event -= 1;
-                while(valread < MAXBUFFLEN){
-                    n = read(client_fd, client_buff[i] + valread, MAXBUFFLEN - valread);
-                    if(n < 0 && errno != EAGAIN){
-
-                        printf("fatal\n");
-
-                        keep = 0;
-                        break;
-                    } else if (n < 0 && errno == EAGAIN){
-
-                        break;
-                    }
-                    valread += n;
-                }
-                
-            }
-        }
-
-    }
-
-    return 0;
-}
-
-
-int run_poll(int fd, struct sockaddr_in* servaddr){
-
-
-    int connections = 0;
-
-    int event = 0;
-    struct pollfd* pollfds = NULL;
-    int servlen;
-    int valread;
-    int n;
-    int client_fd;
-
-    int keep = 1;
-
-    servlen = sizeof(*servaddr);   
-
-    pollfds = (struct pollfd*)malloc((client_num + 1) * sizeof(struct pollfd));
-
-    memset(pollfds, 0, (client_num + 1) * sizeof(struct pollfd));
-
-    pollfds[0].fd = fd;
-    pollfds[0].events = POLLIN;
-
-    for(int i = 1; i < client_num + 1; i++){
-
-        pollfds[i].fd = 0;
-        pollfds[i].events = POLLIN;
-
-    }
-
-    while(keep){
-
-        event = poll(pollfds, client_num + 1, -1);
-
-        if ((event < 0 ) && (errno != EINTR)){
-            printf("poll error\n");
-            break;
-        }
-
-        do {
-
-            if(pollfds[0].revents & POLLIN){
-
-                int added = 0;
-
-                event -= 1;
-
-                client_fd = accept(fd, (struct sockaddr*)servaddr, (socklen_t*)&servlen);
-                if(client_fd < 0){
-                    printf("failed to accept\n");
-                    break;
-                }
-
-                if(ctl_fd == 0){
-
-                    ctl_fd = client_fd;
-
-                    ctl_runner(ctl_fd);
-
-                    break;
-
-                } else {
-
-                    read(client_fd, hello, 37);
-                    connections += 1;
-
-                    if(connections == client_num){
-                        pthread_mutex_lock(&lock);
-                        write(ctl_fd, ctl_start_1, 1);
-                        write(ctl_fd, ctl_start_2, 1);
-                        pthread_mutex_unlock(&lock);
-                    }
-
-                }
-
-                if(make_socket_non_blocking(client_fd) < 0){
-                    printf("accept non-blocking failed\n");
-                    break;
-                }
-
-                for(int i = 1; i < client_num + 1; i++){
-                    if(pollfds[i].fd == 0){
-                        pollfds[i].fd = client_fd;
-                        added = 1;
-                        break;
-                    }
-                }
-                if(added != 1){
-                    printf("accept slot full\n");
-                    break;
-                }
-
-            }
-
-        } while(0);
-
-        for(int i = 1; i < client_num + 1; i++){
-
-            if(event == 0){
-                break;
-            }
-            
-            if(pollfds[i].fd == 0){
-                continue;
-            }
-
-            if(pollfds[i].revents & POLLIN){
-
-                valread = 0;
-                n = 0;
-                event -= 1;
-                while(valread < MAXBUFFLEN){
-                    n = read(pollfds[i].fd, client_buff[i] + valread, MAXBUFFLEN - valread);
-                    if(n < 0 && errno != EAGAIN){
-
-                        printf("fatal\n");
-
-                        keep = 0;
-                        break;
-                    } else if (n < 0 && errno == EAGAIN){
-
-                        break;
-                    } 
-                    valread += n;
-                }
-
-            }
-
-        }
-
-    }
-
-poll_out:
-
-    free(pollfds);
-
-    return 0;
-}
-
-
-int run_epoll(int fd, struct sockaddr_in* servaddr){
-
-    int connections = 0;
-
-    int event;
-    struct epoll_event ev; 
-    struct epoll_event* evs = NULL;
-    int servlen;
-    int valread;
-    int n;
-    int client_fd;
-
-    int keep = 1;
-
-    int eplfd = 0;
-
-    servlen = sizeof(*servaddr);   
-
-    eplfd = epoll_create1(0);
-
-    if(eplfd == -1){
-        printf("failed to create epoll fd\n");
-        return -1;
-    }
-
-    evs = (struct epoll_event*)malloc((client_num + 1) * sizeof(struct epoll_event));
-
-    memset(evs, 0, (client_num + 1) * sizeof(struct epoll_event));
-
-    ev.data.fd = fd;
-    ev.events = EPOLLIN;
-
-    if(epoll_ctl(eplfd, EPOLL_CTL_ADD, fd, &ev) < 0){
-        printf("epoll add failed\n");
-        return -1;
-    }
-
-    while(keep){
-
-        event = epoll_wait(eplfd, evs, client_num + 1, -1);
-
-        for(int i = 0 ; i < event; i++){
-
-            if (
-                evs[i].events & EPOLLHUP ||
-                evs[i].events & EPOLLERR ||
-                (!(evs[i].events & EPOLLIN))
-            ){
-                continue;
-            }
-
-            if(evs[i].data.fd == fd){
-
-                int added = 0;
-
-                client_fd = accept(fd, (struct sockaddr*)servaddr, (socklen_t*)&servlen);
-                if(client_fd < 0){
-                    printf("failed to accept\n");
-                    continue;
-                }
-                if(ctl_fd == 0){
-
-                    ctl_fd = client_fd;
-
-                    ctl_runner(ctl_fd);
-
-                    continue;
-
-                } else {
-
-                    int nn = read(client_fd, hello, 37);
-
-                    connections += 1;
-
-                    if(connections == client_num){
-
-                        pthread_mutex_lock(&lock);
-                        write(ctl_fd, ctl_start_1, 1);
-                        write(ctl_fd, ctl_start_2, 1);
-                        pthread_mutex_unlock(&lock);
-                    }
-
-                }
-
-                if(make_socket_non_blocking(client_fd) < 0){
-                    printf("accept non-blocking failed\n");
-                    continue;
-                }
-
-
-                ev.data.fd = client_fd;
-                ev.events = EPOLLIN ;
-
-                if(epoll_ctl(eplfd, EPOLL_CTL_ADD, client_fd, &ev) < 0){
-                    printf("epoll add client failed\n");
-                    continue;
-                }
-
-            } else {
-
-                valread = 0;
-                n = 0;
-                while(valread < MAXBUFFLEN){
-                    n = read(evs[i].data.fd, client_buff[i] + valread, MAXBUFFLEN - valread);
-                    if(n < 0 && errno != EAGAIN){
-
-                        printf("fatal\n");
-
-                        keep = 0;
-                        break;
-                    } else if (n < 0 && errno == EAGAIN){
-
-                        break;
-                    }
-                    valread += n;
-                }
-
-            }
-
-        }
-
-    }
-
-epoll_out:
-
-    free(evs);
-
-    return 0;
-}
\ No newline at end of file
diff --git a/iperf/iperf_s.h b/iperf/iperf_s.h
deleted file mode 100644 (file)
index b7fe5ea..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef _IPERF_S_H_
-#define _IPERF_S_H_
-
-#include <stdio.h> 
-#include <netdb.h> 
-#include <netinet/in.h> 
-#include <arpa/inet.h>
-#include <stdlib.h> 
-#include <string.h> 
-#include <sys/socket.h> 
-#include <sys/types.h> 
-#include <unistd.h> 
-#include <stdint.h>
-#include <pthread.h>
-#include <signal.h>
-#include <time.h>
-#include <sys/time.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <sys/epoll.h>
-#include <errno.h>
-
-#define MAXCLIENT 129
-#define MAXBUFFLEN 65536
-
-extern char mode;
-extern unsigned short port;
-extern int client_num;
-extern int timeout;
-extern int ctl_fd;
-extern uint8_t client_buff[MAXCLIENT][MAXBUFFLEN];
-
-extern pthread_mutex_t lock;
-
-int make_socket_non_blocking (int sfd);
-
-void* ctl_thread(void* varg);
-
-void ctl_runner();
-
-int run_select(int fd, struct sockaddr_in* servaddr);
-
-int run_poll(int fd, struct sockaddr_in* servaddr);
-
-int run_epoll(int fd, struct sockaddr_in* servaddr);
-
-
-
-
-#endif
\ No newline at end of file
diff --git a/iperf/main.c b/iperf/main.c
deleted file mode 100644 (file)
index 3807cdf..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-#include "iperf_s.h"
-
-
-char mode = 's';
-unsigned short port = 5001;
-int client_num = 1;
-int timeout = 5;
-
-int ctl_fd = 0;
-uint8_t client_buff[MAXCLIENT][MAXBUFFLEN];
-
-pthread_mutex_t lock;
-
-static void help(){
-
-    printf("arguments: mode port client_num timeout\n");
-        
-    printf("mode: s - select, p - poll, e - epoll\n");
-}
-
-int main(int argc, char** argv){
-
-    int result = -1;
-
-    int sockfd;
-    int opt = 1;
-    struct sockaddr_in servaddr;
-
-    if(argc != 5){
-
-        help();
-
-        return -1;
-    }
-
-    memset(client_buff, 0, MAXCLIENT * MAXBUFFLEN);
-
-    if(strcmp(argv[1], "s") == 0){
-
-        mode = 's';
-    } else if(strcmp(argv[1], "p") == 0){
-
-        mode = 'p';
-    } else if(strcmp(argv[1], "e") == 0){
-
-        mode = 'e';
-    } else {
-
-        printf("invalid mode: %s\n", argv[1]);
-        help();
-
-        return -1;
-    }
-
-    sscanf(argv[2], "%hd", &port);
-
-    printf("port to use: %hd\n", port);
-
-    sscanf(argv[3], "%d", &client_num);
-
-    printf("client num: %d\n", client_num);
-
-    if(client_num > MAXCLIENT){
-
-        printf("too many clients: %d\n", client_num);
-
-        return -1;
-    }
-
-    sscanf(argv[4], "%d", &timeout);
-
-    printf("timeout: %d\n", timeout);
-
-    pthread_mutex_init(&lock, NULL);
-
-    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
-    if (sockfd == -1) { 
-        printf("socket creation failed\n"); 
-        return -1;
-    } else {
-        printf("socket successfully created\n"); 
-    }
-
-    if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ){  
-        printf("setsockopt failed\n");   
-        return -1;   
-    }   
-    
-    memset(&servaddr, 0, sizeof(servaddr));
-    servaddr.sin_family = AF_INET; 
-    servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
-    servaddr.sin_port = htons(port); 
-   
-    if ((bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) != 0) { 
-        printf("socket bind failed\n"); 
-        return -1; 
-    } 
-   
-    if(make_socket_non_blocking(sockfd) < 0){
-        printf("non-blocking failed\n");
-        return -1;
-    }
-    
-    if ((listen(sockfd, client_num + 1)) != 0) { 
-        printf("listen failed\n"); 
-        return -1;
-    } 
-    if(mode == 's'){
-
-        result = run_select(sockfd, &servaddr);
-
-    } else if (mode == 'p') {
-
-        result = run_poll(sockfd, &servaddr);
-
-    } else if (mode == 'e') {
-
-        result = run_epoll(sockfd, &servaddr);
-    }
-
-    return result;
-}
\ No newline at end of file
diff --git a/iperf/setup.sh b/iperf/setup.sh
deleted file mode 100755 (executable)
index 2cddf3e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash 
-
-
-echo "creating interface..."
-
-sudo ip netns add net1
-
-sudo ip link add dev veth11 type veth peer name veth12 netns net1
-
-sudo ip link set up veth11
-
-sudo ip netns exec net1 ip link set up veth12
-
-sudo ip addr add 192.168.62.5/24 dev veth11
-
-sudo ip netns exec net1 ip addr add 192.168.62.6/24 dev veth12
-
-echo "creating interface!"
diff --git a/ten-k/2505-03.xyz.md b/ten-k/2505-03.xyz.md
new file mode 100644 (file)
index 0000000..d600892
--- /dev/null
@@ -0,0 +1,445 @@
+# 
+
+```shell
+
+./setup.sh
+
+```
+
+#
+
+
+```shell
+
+make
+
+
+```
+
+
+# 
+
+```c
+
+
+
+#define MAXCLIENT 10000
+#define CLIENTS_PER_THREAD 100
+#define THREAD_ITER 100
+#define MAXBUFFLEN 65536
+#define PORT 9999
+
+extern char mode;
+extern char server_mode;
+
+extern int client_num;
+extern uint8_t** client_buff;
+
+extern int wfds[MAXCLIENT];
+extern uint8_t wbuff[MAXCLIENT / CLIENTS_PER_THREAD][MAXBUFFLEN];
+extern atomic_uint_fast8_t wdones[MAXCLIENT / CLIENTS_PER_THREAD];
+
+
+void* run_client_thread(void* varg);
+
+int make_socket_non_blocking (int sfd);
+
+
+
+int run_select(int fd, struct sockaddr_in* servaddr);
+
+int run_poll(int fd, struct sockaddr_in* servaddr);
+
+int run_epoll(int fd, struct sockaddr_in* servaddr);
+
+```
+
+
+# 
+
+```c
+
+        FD_ZERO(&readfds);
+        FD_SET(fd, &readfds);
+        max_fd = fd;
+
+        for(int i = 0; i < client_num; i++){
+            client_fd = client_fds[i];
+
+            if(client_fd > 0){
+                FD_SET(client_fd, &readfds);
+            }
+            if(client_fd > max_fd){
+                max_fd = client_fd;
+            }
+            
+        }
+
+        event = select(max_fd + 1, &readfds, NULL, NULL, NULL);
+
+```
+
+#
+
+```c
+
+    pollfds[0].fd = fd;
+    pollfds[0].events = POLLIN;
+
+    for(int i = 1; i < client_num + 1; i++){
+
+        pollfds[i].fd = 0;
+        pollfds[i].events = POLLIN;
+
+    }
+
+    while(keep){
+
+        event = poll(pollfds, client_num + 1, -1);
+
+
+        do {
+
+            if(pollfds[0].revents & POLLIN){
+
+...
+
+
+        for(int i = 1; i < client_num + 1; i++){
+
+            idx = i - 1;
+
+            if(event == 0){
+                break;
+            }
+            
+            if(pollfds[i].fd == 0){
+                continue;
+            }
+
+            if(pollfds[i].revents & POLLIN){
+
+
+```
+
+#
+
+```c
+
+
+    ev.data.fd = fd;
+    ev.events = EPOLLIN;
+
+    if(epoll_ctl(eplfd, EPOLL_CTL_ADD, fd, &ev) < 0){
+        printf("epoll add failed\n");
+        return -1;
+    }
+
+    while(keep){
+
+        event = epoll_wait(eplfd, evs, client_num + 1, -1);
+
+        for(int i = 0 ; i < event; i++){
+
+            if (
+                evs[i].events & EPOLLHUP ||
+                evs[i].events & EPOLLERR ||
+                (!(evs[i].events & EPOLLIN))
+            ){
+                continue;
+            }
+
+            if(evs[i].data.fd == fd){
+
+...
+
+            } else {
+
+                if(connections != MAXCLIENT){
+
+                    continue;
+                } else {
+        
+                    if(connections_printed == 0){
+        
+                        printf("connection reached: %d\n", connections);
+                        connections_printed = 1;
+                    }
+                }
+        
+                idx = epoll_get_idx(client_fds, evs[i].data.fd);
+
+                if(idx < 0){
+                    printf("epoll get slot failed\n");
+                    continue;
+                }
+
+```
+
+
+#
+
+
+```shell
+
+...
+DESCRIPTION         top
+       WARNING: select() can monitor only file descriptors numbers that
+       are less than FD_SETSIZE (1024)—an unreasonably low limit for many
+       modern applications—and this limitation will not change.  All
+       modern applications should instead use poll(2) or epoll(7), which
+       do not suffer this limitation.
+...
+
+# https://man7.org/linux/man-pages/man2/select.2.html
+```
+
+
+# 
+
+
+```c
+
+#define MAXCLIENT 1000
+
+```
+
+
+# 
+
+```shell
+
+make clean
+
+make
+
+```
+
+
+# 
+
+```shell
+
+ten-k$ sudo ip netns exec net1 ./tenk.out s s
+socket successfully created
+server mode: select
+
+
+```
+
+```shell
+ten-k$ ./tenk.out c 192.168.62.6
+creating connections: 1000
+connectons : 0...
+connectons : 100...
+connectons : 200...
+connectons : 300...
+connectons : 400...
+connectons : 500...
+connectons : 600...
+connectons : 700...
+connectons : 800...
+connectons : 900...
+created connections: 1000
+creating threads: 10
+created threads: 10
+running...
+done
+sec: 0 ms: 152
+```
+
+#
+
+```shell
+
+ten-k$ sudo ip netns exec net1 ./tenk.out s 
+p
+socket successfully created
+server mode: poll
+```
+
+```shell
+
+ten-k$ ./tenk.out c 192.168.62.6
+client mode: address: 192.168.62.6
+creating connections: 1000
+connectons : 0...
+connectons : 100...
+connectons : 200...
+connectons : 300...
+connectons : 400...
+connectons : 500...
+connectons : 600...
+connectons : 700...
+connectons : 800...
+connectons : 900...
+created connections: 1000
+creating threads: 10
+created threads: 10
+running...
+done
+sec: 0 ms: 193
+```
+
+# 
+
+```shell
+
+ten-k$ sudo ip netns exec net1 ./tenk.out s 
+e
+socket successfully created
+server mode: epoll
+
+```
+
+
+```shell
+ten-k$ ./tenk.out c 192.168.62.6
+client mode: address: 192.168.62.6
+creating connections: 1000
+connectons : 0...
+connectons : 100...
+connectons : 200...
+connectons : 300...
+connectons : 400...
+connectons : 500...
+connectons : 600...
+connectons : 700...
+connectons : 800...
+connectons : 900...
+created connections: 1000
+creating threads: 10
+created threads: 10
+running...
+done
+sec: 0 ms: 125
+
+```
+
+# 
+
+```c
+#define MAXCLIENT 10000
+
+```
+
+#
+
+```shell
+
+make clean
+make
+
+```
+
+#
+
+```shell
+sudo ip netns exec net1 /bin/bash
+
+
+```
+
+```shell
+
+sudo -i
+
+```
+
+# 
+
+```shell
+ten-k# ulimit -n
+1024
+
+ten-k# ulimit -n 10240
+
+
+ten-k# ulimit -n
+10240
+```
+
+#
+
+```shell
+ten-k# ./tenk.out s s
+socket successfully created
+server mode: select
+*** bit out of range 0 - FD_SETSIZE on fd_set ***: terminated
+Aborted (core dumped)
+
+```
+
+```shell
+
+connection with the server failed: 5118
+created connections: 10000
+creating threads: 100
+```
+
+#
+
+```shell
+
+ten-k# ./tenk.out s p
+socket successfully created
+server mode: poll
+```
+```shell
+ten-k# ./tenk.out c 192.168.62.6
+client mode: address: 192.168.62.6
+creating connections: 10000
+connectons : 0...
+connectons : 100...
+connectons : 200...
+connectons : 300...
+connectons : 400.
+...
+connectons : 9500...
+connectons : 9600...
+connectons : 9700...
+connectons : 9800...
+connectons : 9900...
+created connections: 10000
+creating threads: 100
+created threads: 100
+running...
+done
+sec: 3 ms: 453
+
+```
+
+#
+
+```shell
+ten-k# ./tenk.out s e
+socket successfully created
+server mode: epoll
+```
+
+```shell
+ten-k# ./tenk.out c 192.168.62.6
+client mode: address: 192.168.62.6
+creating connections: 10000
+connectons : 0...
+connectons : 100...
+connectons : 200...
+connectons : 300...
+connectons : 400...
+connectons : 500...
+connectons : 600...
+...
+connectons : 9300...
+connectons : 9400...
+connectons : 9500...
+connectons : 9600...
+connectons : 9700...
+connectons : 9800...
+connectons : 9900...
+created connections: 10000
+creating threads: 100
+created threads: 100
+running...
+done
+sec: 0 ms: 139
+```
\ No newline at end of file
diff --git a/ten-k/Makefile b/ten-k/Makefile
new file mode 100644 (file)
index 0000000..6780da3
--- /dev/null
@@ -0,0 +1,13 @@
+GCC_FLAGS := -Wall -O2 -g
+
+all: tenk.o
+
+       gcc $(GCC_FLAGS) -I. -o tenk.out main.c tenk.o -lpthread
+
+
+tenk.o: 
+
+       gcc $(GCC_FLAGS) -c -I. -o tenk.o tenk.c
+
+clean:
+       rm -r *.o *.a *.so *.out
\ No newline at end of file
diff --git a/ten-k/main.c b/ten-k/main.c
new file mode 100644 (file)
index 0000000..748a69e
--- /dev/null
@@ -0,0 +1,237 @@
+#include "tenk.h"
+
+
+char mode = 's';
+char server_mode = 's';
+
+int client_num = MAXCLIENT;
+uint8_t** client_buff = NULL;
+
+int wfds[MAXCLIENT] = {0};
+uint8_t wbuff[MAXCLIENT/CLIENTS_PER_THREAD][MAXBUFFLEN];
+atomic_uint_fast8_t wdones[MAXCLIENT / CLIENTS_PER_THREAD];
+
+
+
+pthread_mutex_t lock;
+
+static void help(){
+
+    printf("arguments: mode [address|server_mode]\n");
+        
+    printf("mode: c - client, s - server\n");
+    printf("address: server address in client mode\n");
+    printf("server_mode: s - select, p - poll, e - epoll\n");
+}
+
+int main(int argc, char** argv){
+
+    int result = -1;
+
+    int sockfd;
+    int opt = 1;
+    struct sockaddr_in servaddr;
+
+    if(argc != 3){
+
+        help();
+
+        return -1;
+    }
+
+    if(strcmp(argv[1], "c") == 0){
+
+        mode = 'c';
+
+    } else if (strcmp(argv[1], "s") == 0){
+
+        mode = 's';
+    } else {
+
+        printf("invalid mode: %s\n", argv[1]);
+        help();
+
+        return -1;
+
+    }
+
+    if(mode == 'c'){
+
+        printf("client mode: address: %s\n", argv[2]);
+
+        pthread_t tids[MAXCLIENT / CLIENTS_PER_THREAD];
+        int ids[MAXCLIENT / CLIENTS_PER_THREAD];
+
+        int connfd;
+        struct sockaddr_in servaddr;
+
+        printf("creating connections: %d\n", MAXCLIENT);
+
+        for(int i = 0; i < MAXCLIENT; i++){
+
+            connfd = socket(AF_INET, SOCK_STREAM, 0);
+            if (connfd == -1) {
+                printf("client socket creation failed: %d\n", i);
+                result = -1;
+                break;    
+            }
+        
+            memset(&servaddr, 0, sizeof(servaddr));
+
+            servaddr.sin_family = AF_INET;
+            servaddr.sin_addr.s_addr = inet_addr(argv[2]);
+            servaddr.sin_port = htons(PORT);
+         
+            if (connect(connfd, (struct sockaddr*)&servaddr, sizeof(servaddr))!= 0) {
+                printf("connection with the server failed: %d\n", i);
+                result = -1;
+                break;
+            }
+
+            if(i % 100 == 0){
+                printf("connectons : %d...\n", i);
+            }
+
+            wfds[i] = connfd;
+
+        }
+
+        printf("created connections: %d\n", MAXCLIENT);
+
+        int thread_count = MAXCLIENT / CLIENTS_PER_THREAD;
+        
+        printf("creating threads: %d\n", thread_count);
+
+        for(int i = 0; i < thread_count; i++){
+
+            ids[i] = i;
+            wdones[i] = 0;
+            pthread_create(&tids[i], NULL, run_client_thread, (void*)&ids[i]);
+
+        }
+        
+        printf("created threads: %d\n", thread_count);
+
+        printf("running...\n");
+
+        struct timeval t1, t2;
+    
+        gettimeofday(&t1, NULL);
+
+        gettimeofday(&t2, NULL);
+    
+        while(1){
+
+            int count = 0;
+
+            for(int i = 0 ; i < thread_count; i++){
+
+                if(wdones[i] == 1){
+                    count += 1;
+                }
+
+            }
+
+            if(count == thread_count){
+
+                printf("done\n");
+                break;
+            }
+        }
+
+        gettimeofday(&t2, NULL);
+    
+                
+        uint32_t seconds = t2.tv_sec - t1.tv_sec;      
+        uint32_t ms = (t2.tv_usec - t1.tv_usec) / 1000;
+        
+        printf("sec: %lu ms: %lu\n", seconds, ms);
+
+    }
+
+    if(mode == 's'){
+
+        if(strcmp(argv[2], "s") == 0){
+
+            server_mode = 's';
+        } else if(strcmp(argv[2], "p") == 0){
+    
+            server_mode = 'p';
+        } else if(strcmp(argv[2], "e") == 0){
+    
+            server_mode = 'e';
+        } else {
+    
+            printf("invalid server mode: %s\n", argv[2]);
+            help();
+    
+            return -1;
+        }
+
+        client_buff = (uint8_t**)malloc(client_num * sizeof(uint8_t*));
+
+        for(int i = 0; i < client_num; i++){
+
+            client_buff[i] = (uint8_t*)malloc(MAXBUFFLEN * sizeof(uint8_t));
+
+        }
+
+
+        sockfd = socket(AF_INET, SOCK_STREAM, 0); 
+        if (sockfd == -1) { 
+            printf("socket creation failed\n"); 
+            return -1;
+        } else {
+            printf("socket successfully created\n"); 
+        }
+    
+        if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ){  
+            printf("setsockopt failed\n");   
+            return -1;   
+        }   
+        
+        memset(&servaddr, 0, sizeof(servaddr));
+     
+        servaddr.sin_family = AF_INET; 
+        servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
+        servaddr.sin_port = htons(PORT); 
+       
+        if ((bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) != 0) { 
+            printf("socket bind failed\n"); 
+            return -1; 
+        } 
+       
+        if(make_socket_non_blocking(sockfd) < 0){
+            printf("non-blocking failed\n");
+            return -1;
+        }
+        
+        if ((listen(sockfd, client_num + 1)) != 0) { 
+            printf("listen failed\n"); 
+            return -1;
+        } 
+        if(server_mode == 's'){
+    
+            result = run_select(sockfd, &servaddr);
+    
+        } else if (server_mode == 'p') {
+    
+            result = run_poll(sockfd, &servaddr);
+    
+        } else if (server_mode == 'e') {
+    
+            result = run_epoll(sockfd, &servaddr);
+        }
+
+        for(int i = 0 ; i < client_num; i++){
+
+            free(client_buff[i]);
+
+        }
+
+        free(client_buff);
+    }
+
+
+    return result;
+}
\ No newline at end of file
diff --git a/ten-k/setup.sh b/ten-k/setup.sh
new file mode 100755 (executable)
index 0000000..fcc25e3
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash 
+
+
+echo "creating interface..."
+
+sudo ip netns add net1
+
+sudo ip link add dev veth11 type veth peer name veth12 netns net1
+
+sudo ip link set up veth11
+
+sudo ip netns exec net1 ip link set up veth12
+
+sudo ip addr add 192.168.62.5/24 dev veth11
+
+sudo ip netns exec net1 ip addr add 192.168.62.6/24 dev veth12
+
+echo "created interface!"
diff --git a/ten-k/tenk.c b/ten-k/tenk.c
new file mode 100644 (file)
index 0000000..6303627
--- /dev/null
@@ -0,0 +1,536 @@
+#include "tenk.h"
+
+
+
+void* run_client_thread(void* varg){
+
+    int tid = *(int*)varg;
+
+    int fdstart = tid * CLIENTS_PER_THREAD;
+
+    int fdend = tid + CLIENTS_PER_THREAD;
+
+    int count = 0;
+    
+    int n = 0;
+
+    while(count < THREAD_ITER){
+
+        if(getrandom(wbuff[tid], MAXBUFFLEN, 0) < 0){
+
+            printf("getrandom failed\n");
+
+            continue;
+        }
+
+        for(int i = fdstart; i < fdend; i++){
+
+            n = write(wfds[i], wbuff[tid], MAXBUFFLEN);
+
+            if(n <= 0){
+
+                printf("failed to write: %d\n", i);
+
+                continue;
+
+            }
+
+        }
+
+        count += 1;
+
+    }
+
+    wdones[tid] = 1;
+
+    pthread_exit(NULL);
+
+}
+
+
+
+int make_socket_non_blocking(int sfd){
+    int flags, s;
+  
+    flags = fcntl (sfd, F_GETFL, 0);
+    if (flags == -1){
+        printf("fcntl get");
+        return -1;
+    }
+  
+    flags |= O_NONBLOCK;
+    s = fcntl (sfd, F_SETFL, flags);
+    if (s == -1){
+        printf("fcntl set");
+        return -2;
+    } 
+    return 0;
+}
+
+
+int run_select(int fd, struct sockaddr_in* servaddr){
+
+    printf("server mode: select\n");
+
+    int connections = 0;
+    int connections_printed = 0;
+
+    int max_fd = 0;
+    int event = 0;
+    fd_set readfds;
+    int servlen;
+    int client_fds[MAXCLIENT] = {0};
+    int valread;
+    int n;
+    int client_fd;
+
+    int keep = 1;
+
+    servlen = sizeof(*servaddr);   
+    
+    while(keep){
+
+        FD_ZERO(&readfds);
+        FD_SET(fd, &readfds);
+        max_fd = fd;
+
+        for(int i = 0; i < client_num; i++){
+            client_fd = client_fds[i];
+
+            if(client_fd > 0){
+                FD_SET(client_fd, &readfds);
+            }
+            if(client_fd > max_fd){
+                max_fd = client_fd;
+            }
+            
+        }
+
+        event = select(max_fd + 1, &readfds, NULL, NULL, NULL);
+
+        if ((event < 0 ) && (errno != EINTR)){
+            printf("select error\n");
+            break;
+        }
+
+        do {
+            if(FD_ISSET(fd, &readfds)){
+                int added = 0;
+                event -= 1;
+                client_fd = accept(fd, (struct sockaddr*)servaddr, (socklen_t*)&servlen);
+
+                if(client_fd < 0){
+
+                    break;
+                }
+
+
+                if(make_socket_non_blocking(client_fd) < 0){
+                    printf("accept non-blocking failed\n");
+                    break;
+                }
+                for(int i = 0; i < client_num; i++){
+                    if(client_fds[i] == 0){
+                        client_fds[i] = client_fd;
+                        added = 1;
+                        break;
+                    }
+                }
+                if(added != 1){
+                    printf("accept slot full\n");
+                    break;
+                }
+
+                connections += 1;
+
+            }
+        } while(0);
+
+        if(connections != MAXCLIENT){
+
+            continue;
+        } else {
+
+            if(connections_printed == 0){
+
+                printf("connection reached: %d\n", connections);
+                connections_printed = 1;
+            }
+        }
+
+        for(int i = 0; i < client_num; i++){
+            if(event == 0){
+                break;
+            }
+            client_fd = client_fds[i];
+            if(client_fd == 0){
+                continue;
+            }
+            if(FD_ISSET(client_fd, &readfds)){
+                valread = 0;
+                n = 0;
+                event -= 1;
+                while(valread < MAXBUFFLEN){
+                    n = read(client_fd, client_buff[i] + valread, MAXBUFFLEN - valread);
+                    if(n < 0 && errno != EAGAIN){
+
+                        printf("fatal\n");
+
+                        keep = 0;
+                        break;
+                    } else if (n < 0 && errno == EAGAIN){
+
+                        break;
+                    }
+                    valread += n;
+                }
+                
+            }
+        }
+
+    }
+
+    return 0;
+}
+
+
+int run_poll(int fd, struct sockaddr_in* servaddr){
+
+    printf("server mode: poll\n");
+
+
+    int connections = 0;
+    int connections_printed = 0;
+
+    int event = 0;
+    struct pollfd* pollfds = NULL;
+    int servlen;
+    int valread;
+    int n;
+    int client_fd;
+
+    int idx;
+
+    int keep = 1;
+
+    servlen = sizeof(*servaddr);   
+
+    pollfds = (struct pollfd*)malloc((client_num + 1) * sizeof(struct pollfd));
+
+    memset(pollfds, 0, (client_num + 1) * sizeof(struct pollfd));
+
+    pollfds[0].fd = fd;
+    pollfds[0].events = POLLIN;
+
+    for(int i = 1; i < client_num + 1; i++){
+
+        pollfds[i].fd = 0;
+        pollfds[i].events = POLLIN;
+
+    }
+
+    while(keep){
+
+        event = poll(pollfds, client_num + 1, -1);
+
+
+        do {
+
+            if(pollfds[0].revents & POLLIN){
+
+                int added = 0;
+
+                event -= 1;
+
+                client_fd = accept(fd, (struct sockaddr*)servaddr, (socklen_t*)&servlen);
+                if(client_fd < 0){
+
+                    break;
+                }
+
+                if(make_socket_non_blocking(client_fd) < 0){
+                    printf("accept non-blocking failed\n");
+                    break;
+                }
+
+                for(int i = 1; i < client_num + 1; i++){
+                    if(pollfds[i].fd == 0){
+                        pollfds[i].fd = client_fd;
+                        added = 1;
+                        break;
+                    }
+                }
+                if(added != 1){
+                    printf("accept slot full\n");
+                    break;
+                }
+
+                connections += 1;
+
+            }
+
+        } while(0);
+
+        if(connections != MAXCLIENT){
+
+            continue;
+        } else {
+
+            if(connections_printed == 0){
+
+                printf("connection reached: %d\n", connections);
+                connections_printed = 1;
+            }
+        }
+
+
+        for(int i = 1; i < client_num + 1; i++){
+
+            idx = i - 1;
+
+            if(event == 0){
+                break;
+            }
+            
+            if(pollfds[i].fd == 0){
+                continue;
+            }
+
+            if(pollfds[i].revents & POLLIN){
+
+                valread = 0;
+                n = 0;
+                event -= 1;
+                while(valread < MAXBUFFLEN){
+                    n = read(pollfds[i].fd, client_buff[idx] + valread, MAXBUFFLEN - valread);
+                    if(n < 0 && errno != EAGAIN){
+
+                        printf("fatal\n");
+
+                        keep = 0;
+                        break;
+                    } else if (n < 0 && errno == EAGAIN){
+
+                        break;
+                    } 
+                    valread += n;
+                }
+
+            }
+
+        }
+
+    }
+
+poll_out:
+
+    free(pollfds);
+
+    return 0;
+}
+
+static inline int epoll_add_idx(int* client_fds, int fd){
+
+    int done = 0;
+    int idx = fd % MAXCLIENT;
+    int start_idx = idx;
+
+    while(done == 0){
+
+        if(client_fds[idx] == 0){
+
+            client_fds[idx] = fd;
+
+            done = idx;
+
+            break;
+        } else {
+            idx += 1;
+        }
+
+        if(idx == MAXCLIENT){
+            idx = 0;
+        }
+
+        if(idx == start_idx){
+            done = -1;
+        }
+
+    }
+
+    return done;
+}
+
+static inline int epoll_get_idx(int* client_fds, int fd){
+
+    int done = 0;
+    int idx = fd % MAXCLIENT;
+    int start_idx = idx;
+
+    while(done == 0){
+
+        if(client_fds[idx] == fd){
+
+            done = idx;
+
+            break;
+        } else {
+            idx += 1;
+        }
+
+        if(idx == MAXCLIENT){
+            idx = 0;
+        }
+
+        if(idx == start_idx){
+            done = -1;
+        }
+
+    }
+
+    return done;
+}
+
+int run_epoll(int fd, struct sockaddr_in* servaddr){
+
+    printf("server mode: epoll\n");
+
+
+    int connections = 0;
+    int connections_printed = 0;
+
+    int event;
+    struct epoll_event ev; 
+    struct epoll_event* evs = NULL;
+    int servlen;
+    int valread;
+    int n;
+    int client_fd;
+
+    int client_fds[MAXCLIENT] = {0};
+
+    int idx;
+
+    int keep = 1;
+
+    int eplfd = 0;
+
+    servlen = sizeof(*servaddr);   
+
+    eplfd = epoll_create1(0);
+
+    if(eplfd == -1){
+        printf("failed to create epoll fd\n");
+        return -1;
+    }
+
+    evs = (struct epoll_event*)malloc((client_num + 1) * sizeof(struct epoll_event));
+
+    memset(evs, 0, (client_num + 1) * sizeof(struct epoll_event));
+
+    ev.data.fd = fd;
+    ev.events = EPOLLIN;
+
+    if(epoll_ctl(eplfd, EPOLL_CTL_ADD, fd, &ev) < 0){
+        printf("epoll add failed\n");
+        return -1;
+    }
+
+    while(keep){
+
+        event = epoll_wait(eplfd, evs, client_num + 1, -1);
+
+        for(int i = 0 ; i < event; i++){
+
+            if (
+                evs[i].events & EPOLLHUP ||
+                evs[i].events & EPOLLERR ||
+                (!(evs[i].events & EPOLLIN))
+            ){
+                continue;
+            }
+
+            if(evs[i].data.fd == fd){
+
+                int added = 0;
+
+                client_fd = accept(fd, (struct sockaddr*)servaddr, (socklen_t*)&servlen);
+                if(client_fd < 0){
+
+                    continue;
+                }
+
+
+                if(make_socket_non_blocking(client_fd) < 0){
+                    printf("accept non-blocking failed\n");
+                    continue;
+                }
+
+
+                ev.data.fd = client_fd;
+                ev.events = EPOLLIN ;
+
+                if(epoll_ctl(eplfd, EPOLL_CTL_ADD, client_fd, &ev) < 0){
+                    printf("epoll add client failed\n");
+                    continue;
+                }
+
+                idx = epoll_add_idx(client_fds, client_fd);
+
+                if(idx < 0){
+                    printf("epoll add slot full\n");
+                    continue;
+                }
+
+                connections += 1;
+
+            } else {
+
+                if(connections != MAXCLIENT){
+
+                    continue;
+                } else {
+        
+                    if(connections_printed == 0){
+        
+                        printf("connection reached: %d\n", connections);
+                        connections_printed = 1;
+                    }
+                }
+        
+                idx = epoll_get_idx(client_fds, evs[i].data.fd);
+
+                if(idx < 0){
+                    printf("epoll get slot failed\n");
+                    continue;
+                }
+
+                valread = 0;
+                n = 0;
+                while(valread < MAXBUFFLEN){
+                    n = read(evs[i].data.fd, client_buff[idx] + valread, MAXBUFFLEN - valread);
+                    if(n < 0 && errno != EAGAIN){
+
+                        printf("fatal\n");
+
+                        keep = 0;
+                        break;
+                    } else if (n < 0 && errno == EAGAIN){
+
+                        break;
+                    }
+                    valread += n;
+                }
+
+            }
+
+        }
+
+    }
+
+epoll_out:
+
+    free(evs);
+
+    return 0;
+}
\ No newline at end of file
diff --git a/ten-k/tenk.h b/ten-k/tenk.h
new file mode 100644 (file)
index 0000000..5147e52
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef _TEN_K_H_
+#define _TEN_K_H_
+
+#include <stdio.h> 
+#include <netdb.h> 
+#include <netinet/in.h> 
+#include <arpa/inet.h>
+#include <stdlib.h> 
+#include <string.h> 
+#include <sys/socket.h> 
+#include <sys/types.h> 
+#include <unistd.h> 
+#include <stdint.h>
+#include <pthread.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <sys/epoll.h>
+#include <errno.h>
+#include <stdatomic.h>
+#include <sys/time.h>
+#include <sys/random.h>
+
+#define MAXCLIENT 10000
+#define CLIENTS_PER_THREAD 100
+#define THREAD_ITER 100
+#define MAXBUFFLEN 65536
+#define PORT 9999
+
+extern char mode;
+extern char server_mode;
+
+extern int client_num;
+extern uint8_t** client_buff;
+
+extern int wfds[MAXCLIENT];
+extern uint8_t wbuff[MAXCLIENT / CLIENTS_PER_THREAD][MAXBUFFLEN];
+extern atomic_uint_fast8_t wdones[MAXCLIENT / CLIENTS_PER_THREAD];
+
+
+void* run_client_thread(void* varg);
+
+int make_socket_non_blocking (int sfd);
+
+
+
+int run_select(int fd, struct sockaddr_in* servaddr);
+
+int run_poll(int fd, struct sockaddr_in* servaddr);
+
+int run_epoll(int fd, struct sockaddr_in* servaddr);
+
+
+
+
+#endif
\ No newline at end of file