benchmark-ping-pongs.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 "uv.h"
23 #include "task.h"
24 
25 #include <stdlib.h>
26 #include <stdio.h>
27 
28 /* Run the benchmark for this many ms */
29 #define TIME 5000
30 
31 
32 typedef struct {
33  int pongs;
34  int state;
38 } pinger_t;
39 
40 typedef struct buf_s {
42  struct buf_s* next;
43 } buf_t;
44 
45 
46 static char PING[] = "PING\n";
47 
48 static uv_loop_t* loop;
49 
50 static buf_t* buf_freelist = NULL;
52 static int completed_pingers = 0;
54 
55 
56 static void buf_alloc(uv_handle_t* tcp, size_t size, uv_buf_t* buf) {
57  buf_t* ab;
58 
59  ab = buf_freelist;
60  if (ab != NULL)
61  buf_freelist = ab->next;
62  else {
63  ab = malloc(size + sizeof(*ab));
64  ab->uv_buf_t.len = size;
65  ab->uv_buf_t.base = (char*) (ab + 1);
66  }
67 
68  *buf = ab->uv_buf_t;
69 }
70 
71 
72 static void buf_free(const uv_buf_t* buf) {
73  buf_t* ab = (buf_t*) buf->base - 1;
74  ab->next = buf_freelist;
75  buf_freelist = ab;
76 }
77 
78 
80  pinger_t* pinger;
81 
82  pinger = (pinger_t*)handle->data;
83  fprintf(stderr, "ping_pongs: %d roundtrips/s\n", (1000 * pinger->pongs) / TIME);
84  fflush(stderr);
85 
86  free(pinger);
87 
89 }
90 
91 
92 static void pinger_write_cb(uv_write_t* req, int status) {
93  ASSERT(status == 0);
94 
95  free(req);
96 }
97 
98 
99 static void pinger_write_ping(pinger_t* pinger) {
100  uv_write_t* req;
101  uv_buf_t buf;
102 
103  buf = uv_buf_init(PING, sizeof(PING) - 1);
104 
105  req = malloc(sizeof *req);
106  if (uv_write(req, (uv_stream_t*) &pinger->tcp, &buf, 1, pinger_write_cb)) {
107  FATAL("uv_write failed");
108  }
109 }
110 
111 
113  ASSERT(status == 0);
115 
116  /*
117  * The close callback has not been triggered yet. We must wait for EOF
118  * until we close the connection.
119  */
121 }
122 
123 
125  ssize_t nread,
126  const uv_buf_t* buf) {
127  ssize_t i;
128  pinger_t* pinger;
129 
130  pinger = (pinger_t*)tcp->data;
131 
132  if (nread < 0) {
133  ASSERT(nread == UV_EOF);
134 
135  if (buf->base) {
136  buf_free(buf);
137  }
138 
141 
142  return;
143  }
144 
145  /* Now we count the pings */
146  for (i = 0; i < nread; i++) {
147  ASSERT(buf->base[i] == PING[pinger->state]);
148  pinger->state = (pinger->state + 1) % (sizeof(PING) - 1);
149  if (pinger->state == 0) {
150  pinger->pongs++;
151  if (uv_now(loop) - start_time > TIME) {
152  uv_shutdown(&pinger->shutdown_req,
153  (uv_stream_t*) tcp,
155  break;
156  } else {
157  pinger_write_ping(pinger);
158  }
159  }
160  }
161 
162  buf_free(buf);
163 }
164 
165 
167  pinger_t *pinger = (pinger_t*)req->handle->data;
168 
169  ASSERT(status == 0);
170 
171  pinger_write_ping(pinger);
172 
174  FATAL("uv_read_start failed");
175  }
176 }
177 
178 
179 static void pinger_new(void) {
180  struct sockaddr_in client_addr;
181  struct sockaddr_in server_addr;
182  pinger_t *pinger;
183  int r;
184 
185  ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &client_addr));
186  ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
187  pinger = malloc(sizeof(*pinger));
188  pinger->state = 0;
189  pinger->pongs = 0;
190 
191  /* Try to connect to the server and do NUM_PINGS ping-pongs. */
192  r = uv_tcp_init(loop, &pinger->tcp);
193  ASSERT(!r);
194 
195  pinger->tcp.data = pinger;
196 
197  ASSERT(0 == uv_tcp_bind(&pinger->tcp,
198  (const struct sockaddr*) &client_addr,
199  0));
200 
201  r = uv_tcp_connect(&pinger->connect_req,
202  &pinger->tcp,
203  (const struct sockaddr*) &server_addr,
205  ASSERT(!r);
206 }
207 
208 
209 BENCHMARK_IMPL(ping_pongs) {
210  loop = uv_default_loop();
211 
213 
214  pinger_new();
216 
218 
220  return 0;
221 }
loop
static uv_loop_t * loop
Definition: benchmark-ping-pongs.c:48
task.h
pinger_write_cb
static void pinger_write_cb(uv_write_t *req, int status)
Definition: benchmark-ping-pongs.c:92
uv_connect_s
Definition: uv.h:580
uv_now
UV_EXTERN uint64_t uv_now(const uv_loop_t *)
Definition: uv-common.c:537
uv_shutdown_s
Definition: uv.h:417
pinger_t::pongs
int pongs
Definition: benchmark-ping-pongs.c:33
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
uv_connect_s::handle
uv_stream_t * handle
Definition: uv.h:583
ASSERT
#define ASSERT(expr)
Definition: task.h:102
tcp
static uv_tcp_t tcp
Definition: test-connection-fail.c:29
status
absl::Status status
Definition: rls.cc:251
buf_s::next
struct buf_s * next
Definition: benchmark-ping-pongs.c:42
TIME
#define TIME
Definition: benchmark-ping-pongs.c:29
uv_run
UV_EXTERN int uv_run(uv_loop_t *, uv_run_mode mode)
Definition: unix/core.c:361
pinger_shutdown_cb_called
static int pinger_shutdown_cb_called
Definition: benchmark-ping-pongs.c:51
buf_s::uv_buf_t
uv_buf_t uv_buf_t
Definition: benchmark-ping-pongs.c:41
pinger_connect_cb
static void pinger_connect_cb(uv_connect_t *req, int status)
Definition: benchmark-ping-pongs.c:166
uv_tcp_bind
UV_EXTERN int uv_tcp_bind(uv_tcp_t *handle, const struct sockaddr *addr, unsigned int flags)
Definition: uv-common.c:277
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
start_time
static int64_t start_time
Definition: benchmark-ping-pongs.c:53
uv_default_loop
UV_EXTERN uv_loop_t * uv_default_loop(void)
Definition: uv-common.c:733
ssize_t
intptr_t ssize_t
Definition: win.h:27
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
buf_alloc
static void buf_alloc(uv_handle_t *tcp, size_t size, uv_buf_t *buf)
Definition: benchmark-ping-pongs.c:56
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
pinger_read_cb
static void pinger_read_cb(uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf)
Definition: benchmark-ping-pongs.c:124
req
static uv_connect_t req
Definition: test-connection-fail.c:30
UV_RUN_DEFAULT
@ UV_RUN_DEFAULT
Definition: uv.h:254
BENCHMARK_IMPL
BENCHMARK_IMPL(ping_pongs)
Definition: benchmark-ping-pongs.c:209
uv_shutdown
UV_PRIVATE_REQ_TYPES UV_EXTERN int uv_shutdown(uv_shutdown_t *req, uv_stream_t *handle, uv_shutdown_cb cb)
Definition: unix/stream.c:1259
pinger_t::tcp
uv_tcp_t tcp
Definition: benchmark-ping-pongs.c:35
buf_t
struct buf_s buf_t
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
pinger_close_cb
static void pinger_close_cb(uv_handle_t *handle)
Definition: benchmark-ping-pongs.c:79
completed_pingers
static int completed_pingers
Definition: benchmark-ping-pongs.c:52
uv_tcp_init
UV_EXTERN int uv_tcp_init(uv_loop_t *, uv_tcp_t *handle)
Definition: unix/tcp.c:143
pinger_shutdown_cb
static void pinger_shutdown_cb(uv_shutdown_t *req, int status)
Definition: benchmark-ping-pongs.c:112
uv_tcp_s
Definition: uv.h:544
uv_buf_t::base
char * base
Definition: unix.h:122
pinger_t::connect_req
uv_connect_t connect_req
Definition: benchmark-ping-pongs.c:36
pinger_t::shutdown_req
uv_shutdown_t shutdown_req
Definition: benchmark-ping-pongs.c:37
uv.h
pinger_t::state
int state
Definition: benchmark-ping-pongs.c:34
MAKE_VALGRIND_HAPPY
#define MAKE_VALGRIND_HAPPY()
Definition: task.h:229
FATAL
#define FATAL(msg)
Definition: task.h:88
uv_buf_t
Definition: unix.h:121
buf_free
static void buf_free(const uv_buf_t *buf)
Definition: benchmark-ping-pongs.c:72
pinger_new
static void pinger_new(void)
Definition: benchmark-ping-pongs.c:179
fix_build_deps.r
r
Definition: fix_build_deps.py:491
pinger_write_ping
static void pinger_write_ping(pinger_t *pinger)
Definition: benchmark-ping-pongs.c:99
pinger_t
Definition: benchmark-ping-pongs.c:32
uv_buf_init
UV_EXTERN uv_buf_t uv_buf_init(char *base, unsigned int len)
Definition: uv-common.c:157
uv_buf_t::len
size_t len
Definition: unix.h:123
uv_write_s
Definition: uv.h:522
handle
static csh handle
Definition: test_arm_regression.c:16
uv_handle_s
Definition: uv.h:441
uv_loop_s
Definition: uv.h:1767
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
PING
static char PING[]
Definition: benchmark-ping-pongs.c:46
buf_s
Definition: benchmark-ping-pongs.c:40
if
if(p->owned &&p->wrapped !=NULL)
Definition: call.c:42
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
buf_freelist
static buf_t * buf_freelist
Definition: benchmark-ping-pongs.c:50


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