benchmark-pound.c
Go to the documentation of this file.
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to
5  * deal in the Software without restriction, including without limitation the
6  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7  * sell copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19  * IN THE SOFTWARE.
20  */
21 
22 #include "task.h"
23 #include "uv.h"
24 
25 /* Update this is you're going to run > 1000 concurrent requests. */
26 #define MAX_CONNS 1000
27 
28 #undef NANOSEC
29 #define NANOSEC ((uint64_t) 1e9)
30 
31 #undef DEBUG
32 #define DEBUG 0
33 
34 struct conn_rec_s;
35 
36 typedef void (*setup_fn)(int num, void* arg);
37 typedef void (*make_connect_fn)(struct conn_rec_s* conn);
39 
40 /* Base class for tcp_conn_rec and pipe_conn_rec.
41  * The ordering of fields matters!
42  */
43 typedef struct conn_rec_s {
44  int i;
49 } conn_rec;
50 
51 typedef struct {
52  int i;
57 } tcp_conn_rec;
58 
59 typedef struct {
60  int i;
66 
67 static char buffer[] = "QS";
68 
69 static uv_loop_t* loop;
70 
73 
74 static uint64_t start; /* in ms */
75 static int closed_streams;
76 static int conns_failed;
77 
78 static void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
79 static void connect_cb(uv_connect_t* conn_req, int status);
80 static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
81 static void close_cb(uv_handle_t* handle);
82 
83 
85  size_t suggested_size,
86  uv_buf_t* buf) {
87  static char slab[65536];
88  buf->base = slab;
89  buf->len = sizeof(slab);
90 }
91 
92 
93 static void after_write(uv_write_t* req, int status) {
94  if (status != 0) {
95  fprintf(stderr, "write error %s\n", uv_err_name(status));
97  conns_failed++;
98  return;
99  }
100 }
101 
102 
103 static void connect_cb(uv_connect_t* req, int status) {
104  conn_rec* conn;
105  uv_buf_t buf;
106  int r;
107 
108  if (status != 0) {
109 #if DEBUG
110  fprintf(stderr, "connect error %s\n", uv_err_name(status));
111 #endif
113  conns_failed++;
114  return;
115  }
116 
117  ASSERT(req != NULL);
118  ASSERT(status == 0);
119 
120  conn = (conn_rec*)req->data;
121  ASSERT(conn != NULL);
122 
123 #if DEBUG
124  printf("connect_cb %d\n", conn->i);
125 #endif
126 
127  r = uv_read_start(&conn->stream, alloc_cb, read_cb);
128  ASSERT(r == 0);
129 
130  buf.base = buffer;
131  buf.len = sizeof(buffer) - 1;
132 
133  r = uv_write(&conn->write_req, &conn->stream, &buf, 1, after_write);
134  ASSERT(r == 0);
135 }
136 
137 
138 static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
139 
140  ASSERT(stream != NULL);
141 
142 #if DEBUG
143  printf("read_cb %d\n", p->i);
144 #endif
145 
147 
148  if (nread < 0) {
149  if (nread == UV_EOF) {
150  ;
151  } else if (nread == UV_ECONNRESET) {
152  conns_failed++;
153  } else {
154  fprintf(stderr, "read error %s\n", uv_err_name(nread));
155  ASSERT(0);
156  }
157  }
158 }
159 
160 
161 static void close_cb(uv_handle_t* handle) {
162  conn_rec* p = (conn_rec*)handle->data;
163 
164  ASSERT(handle != NULL);
165  closed_streams++;
166 
167 #if DEBUG
168  printf("close_cb %d\n", p->i);
169 #endif
170 
171  if (uv_now(loop) - start < 10000) {
172  p->make_connect(p);
173  }
174 }
175 
176 
177 static void tcp_do_setup(int num, void* arg) {
178  int i;
179 
180  for (i = 0; i < num; i++) {
181  tcp_conns[i].i = i;
182  }
183 }
184 
185 
186 static void pipe_do_setup(int num, void* arg) {
187  int i;
188 
189  for (i = 0; i < num; i++) {
190  pipe_conns[i].i = i;
191  }
192 }
193 
194 
195 static void tcp_make_connect(conn_rec* p) {
196  struct sockaddr_in addr;
197  tcp_conn_rec* tp;
198  int r;
199 
200  tp = (tcp_conn_rec*) p;
201 
202  r = uv_tcp_init(loop, (uv_tcp_t*)&p->stream);
203  ASSERT(r == 0);
204 
205  ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
206 
207  r = uv_tcp_connect(&tp->conn_req,
208  (uv_tcp_t*) &p->stream,
209  (const struct sockaddr*) &addr,
210  connect_cb);
211  if (r) {
212  fprintf(stderr, "uv_tcp_connect error %s\n", uv_err_name(r));
213  ASSERT(0);
214  }
215 
216 #if DEBUG
217  printf("make connect %d\n", p->i);
218 #endif
219 
220  p->conn_req.data = p;
221  p->write_req.data = p;
222  p->stream.data = p;
223 }
224 
225 
226 static void pipe_make_connect(conn_rec* p) {
227  int r;
228 
229  r = uv_pipe_init(loop, (uv_pipe_t*)&p->stream, 0);
230  ASSERT(r == 0);
231 
233  (uv_pipe_t*) &p->stream,
235  connect_cb);
236 
237 #if DEBUG
238  printf("make connect %d\n", p->i);
239 #endif
240 
241  p->conn_req.data = p;
242  p->write_req.data = p;
243  p->stream.data = p;
244 }
245 
246 
247 static int tcp_do_connect(int num, make_connect_fn make_connect, void* arg) {
248  int i;
249 
250  for (i = 0; i < num; i++) {
252  tcp_conns[i].make_connect = make_connect;
253  }
254 
255  return 0;
256 }
257 
258 
259 static int pipe_do_connect(int num, make_connect_fn make_connect, void* arg) {
260  int i;
261 
262  for (i = 0; i < num; i++) {
264  pipe_conns[i].make_connect = make_connect;
265  }
266 
267  return 0;
268 }
269 
270 
271 static int pound_it(int concurrency,
272  const char* type,
273  setup_fn do_setup,
275  make_connect_fn make_connect,
276  void* arg) {
277  double secs;
278  int r;
279  uint64_t start_time; /* in ns */
281 
282  loop = uv_default_loop();
283 
285  start = uv_now(loop);
286 
287  /* Run benchmark for at least five seconds. */
288  start_time = uv_hrtime();
289 
290  do_setup(concurrency, arg);
291 
292  r = do_connect(concurrency, make_connect, arg);
293  ASSERT(!r);
294 
296 
297  end_time = uv_hrtime();
298 
299  /* Number of fractional seconds it took to run the benchmark. */
300  secs = (double)(end_time - start_time) / NANOSEC;
301 
302  fprintf(stderr, "%s-conn-pound-%d: %.0f accepts/s (%d failed)\n",
303  type,
304  concurrency,
305  closed_streams / secs,
306  conns_failed);
307  fflush(stderr);
308 
310  return 0;
311 }
312 
313 
314 BENCHMARK_IMPL(tcp4_pound_100) {
315  return pound_it(100,
316  "tcp",
317  tcp_do_setup,
320  NULL);
321 }
322 
323 
324 BENCHMARK_IMPL(tcp4_pound_1000) {
325  return pound_it(1000,
326  "tcp",
327  tcp_do_setup,
330  NULL);
331 }
332 
333 
334 BENCHMARK_IMPL(pipe_pound_100) {
335  return pound_it(100,
336  "pipe",
340  NULL);
341 }
342 
343 
344 BENCHMARK_IMPL(pipe_pound_1000) {
345  return pound_it(1000,
346  "pipe",
350  NULL);
351 }
conns_failed
static int conns_failed
Definition: benchmark-pound.c:76
conn_rec_s::conn_req
uv_connect_t conn_req
Definition: benchmark-pound.c:45
tcp_conns
static tcp_conn_rec tcp_conns[MAX_CONNS]
Definition: benchmark-pound.c:71
connect_cb
static void connect_cb(uv_connect_t *conn_req, int status)
Definition: benchmark-pound.c:103
slab
static char slab[1]
Definition: test-watcher-cross-stop.c:37
task.h
read_cb
static void read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
Definition: benchmark-pound.c:138
pipe_do_connect
static int pipe_do_connect(int num, make_connect_fn make_connect, void *arg)
Definition: benchmark-pound.c:259
uv_pipe_connect
UV_EXTERN void uv_pipe_connect(uv_connect_t *req, uv_pipe_t *handle, const char *name, uv_connect_cb cb)
Definition: unix/pipe.c:173
uv_pipe_init
UV_EXTERN int uv_pipe_init(uv_loop_t *, uv_pipe_t *handle, int ipc)
Definition: unix/pipe.c:33
uv_connect_s
Definition: uv.h:580
loop
static uv_loop_t * loop
Definition: benchmark-pound.c:69
uv_now
UV_EXTERN uint64_t uv_now(const uv_loop_t *)
Definition: uv-common.c:537
after_write
static void after_write(uv_write_t *req, int status)
Definition: benchmark-pound.c:93
pipe_make_connect
static void pipe_make_connect(conn_rec *p)
Definition: benchmark-pound.c:226
conn_rec
Definition: blackhole-server.c:28
tcp_conn_rec::i
int i
Definition: benchmark-pound.c:52
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
printf
_Use_decl_annotations_ int __cdecl printf(const char *_Format,...)
Definition: cs_driver.c:91
tcp_conn_rec
Definition: benchmark-pound.c:51
close_cb
static void close_cb(uv_handle_t *handle)
Definition: benchmark-pound.c:161
uv_connect_s::handle
uv_stream_t * handle
Definition: uv.h:583
end_time
static int64_t end_time
Definition: benchmark-getaddrinfo.c:38
tcp_conn_rec::stream
uv_tcp_t stream
Definition: benchmark-pound.c:56
conn_rec_s::make_connect
make_connect_fn make_connect
Definition: benchmark-pound.c:47
ASSERT
#define ASSERT(expr)
Definition: task.h:102
alloc_cb
static void alloc_cb(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
Definition: benchmark-pound.c:84
status
absl::Status status
Definition: rls.cc:251
connect_fn
int(* connect_fn)(int num, make_connect_fn make_connect, void *arg)
Definition: benchmark-pound.c:38
conn_rec_s
Definition: benchmark-pound.c:43
xds_manager.p
p
Definition: xds_manager.py:60
start_time
static int64_t start_time
Definition: benchmark-getaddrinfo.c:37
uv_run
UV_EXTERN int uv_run(uv_loop_t *, uv_run_mode mode)
Definition: unix/core.c:361
TEST_PORT
#define TEST_PORT
Definition: task.h:53
python_utils.port_server.stderr
stderr
Definition: port_server.py:51
uv_close
UV_EXTERN void uv_close(uv_handle_t *handle, uv_close_cb close_cb)
Definition: unix/core.c:112
uv_stream_s
Definition: uv.h:491
uv_tcp_connect
UV_EXTERN int uv_tcp_connect(uv_connect_t *req, uv_tcp_t *handle, const struct sockaddr *addr, uv_connect_cb cb)
Definition: uv-common.c:315
uv_ip4_addr
UV_EXTERN int uv_ip4_addr(const char *ip, int port, struct sockaddr_in *addr)
Definition: uv-common.c:221
pipe_conn_rec::stream
uv_pipe_t stream
Definition: benchmark-pound.c:64
tcp_conn_rec::write_req
uv_write_t write_req
Definition: benchmark-pound.c:54
pipe_conn_rec::make_connect
make_connect_fn make_connect
Definition: benchmark-pound.c:63
do_connect
static void do_connect(void *arg, grpc_error_handle error)
Definition: api_fuzzer.cc:204
uv_update_time
UV_EXTERN void uv_update_time(uv_loop_t *)
Definition: unix/core.c:413
uv_default_loop
UV_EXTERN uv_loop_t * uv_default_loop(void)
Definition: uv-common.c:733
tcp_conn_rec::conn_req
uv_connect_t conn_req
Definition: benchmark-pound.c:53
start
static uint64_t start
Definition: benchmark-pound.c:74
ssize_t
intptr_t ssize_t
Definition: win.h:27
conn_req
static uv_connect_t conn_req
Definition: test-pipe-connect-prepare.c:41
xds_interop_client.int
int
Definition: xds_interop_client.py:113
pipe_conns
static pipe_conn_rec pipe_conns[MAX_CONNS]
Definition: benchmark-pound.c:72
uv_write
UV_EXTERN int uv_write(uv_write_t *req, uv_stream_t *handle, const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb)
Definition: unix/stream.c:1492
conn_rec_s::stream
uv_stream_t stream
Definition: benchmark-pound.c:48
req
static uv_connect_t req
Definition: test-connection-fail.c:30
tcp_conn_rec::make_connect
make_connect_fn make_connect
Definition: benchmark-pound.c:55
UV_RUN_DEFAULT
@ UV_RUN_DEFAULT
Definition: uv.h:254
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
uv_read_start
UV_EXTERN int uv_read_start(uv_stream_t *, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
Definition: unix/stream.c:1555
arg
Definition: cmdline.cc:40
closed_streams
static int closed_streams
Definition: benchmark-pound.c:75
make_connect_fn
void(* make_connect_fn)(struct conn_rec_s *conn)
Definition: benchmark-pound.c:37
NANOSEC
#define NANOSEC
Definition: benchmark-pound.c:29
uv_tcp_init
UV_EXTERN int uv_tcp_init(uv_loop_t *, uv_tcp_t *handle)
Definition: unix/tcp.c:143
tcp_do_setup
static void tcp_do_setup(int num, void *arg)
Definition: benchmark-pound.c:177
pipe_conn_rec::conn_req
uv_connect_t conn_req
Definition: benchmark-pound.c:61
uv_tcp_s
Definition: uv.h:544
http2_server_health_check.conn
conn
Definition: http2_server_health_check.py:29
uv.h
setup_fn
void(* setup_fn)(int num, void *arg)
Definition: benchmark-pound.c:36
MAKE_VALGRIND_HAPPY
#define MAKE_VALGRIND_HAPPY()
Definition: task.h:229
uv_buf_t
Definition: unix.h:121
pipe_conn_rec
Definition: benchmark-pound.c:59
tcp_do_connect
static int tcp_do_connect(int num, make_connect_fn make_connect, void *arg)
Definition: benchmark-pound.c:247
BENCHMARK_IMPL
BENCHMARK_IMPL(tcp4_pound_100)
Definition: benchmark-pound.c:314
conn_rec_s::write_req
uv_write_t write_req
Definition: benchmark-pound.c:46
uv_hrtime
UV_EXTERN uint64_t uv_hrtime(void)
Definition: unix/core.c:107
fix_build_deps.r
r
Definition: fix_build_deps.py:491
tcp_make_connect
static void tcp_make_connect(conn_rec *p)
Definition: benchmark-pound.c:195
xds_manager.num
num
Definition: xds_manager.py:56
arg
struct arg arg
buffer
static char buffer[]
Definition: benchmark-pound.c:67
uv_pipe_s
Definition: uv.h:757
uv_write_s
Definition: uv.h:522
pound_it
static int pound_it(int concurrency, const char *type, setup_fn do_setup, connect_fn do_connect, make_connect_fn make_connect, void *arg)
Definition: benchmark-pound.c:271
handle
static csh handle
Definition: test_arm_regression.c:16
uv_handle_s
Definition: uv.h:441
TEST_PIPENAME
#define TEST_PIPENAME
Definition: task.h:61
uv_loop_s
Definition: uv.h:1767
MAX_CONNS
#define MAX_CONNS
Definition: benchmark-pound.c:26
conn_rec
struct conn_rec_s conn_rec
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
pipe_conn_rec::i
int i
Definition: benchmark-pound.c:60
pipe_do_setup
static void pipe_do_setup(int num, void *arg)
Definition: benchmark-pound.c:186
uv_err_name
const UV_EXTERN char * uv_err_name(int err)
Definition: uv-common.c:189
pipe_conn_rec::write_req
uv_write_t write_req
Definition: benchmark-pound.c:62
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
conn_rec_s::i
int i
Definition: benchmark-pound.c:44
stream
voidpf stream
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:45