diff --git a/test/benchmark-list.h b/test/benchmark-list.h index 901e5ffa7..f3508fbb2 100644 --- a/test/benchmark-list.h +++ b/test/benchmark-list.h @@ -24,6 +24,7 @@ BENCHMARK_DECLARE (loop_count) BENCHMARK_DECLARE (loop_count_timed) BENCHMARK_DECLARE (loop_alive) BENCHMARK_DECLARE (ping_pongs) +BENCHMARK_DECLARE (ping_pongs_10) BENCHMARK_DECLARE (ping_udp1) BENCHMARK_DECLARE (ping_udp10) BENCHMARK_DECLARE (ping_udp100) @@ -95,6 +96,9 @@ TASK_LIST_START BENCHMARK_ENTRY (ping_pongs) BENCHMARK_HELPER (ping_pongs, tcp4_echo_server) + BENCHMARK_ENTRY (ping_pongs_10) + BENCHMARK_HELPER (ping_pongs_10, tcp4_echo_server) + BENCHMARK_ENTRY (ping_udp1) BENCHMARK_ENTRY (ping_udp10) BENCHMARK_ENTRY (ping_udp100) diff --git a/test/benchmark-ping-pongs.c b/test/benchmark-ping-pongs.c index fd5f40b91..24a7161aa 100644 --- a/test/benchmark-ping-pongs.c +++ b/test/benchmark-ping-pongs.c @@ -28,41 +28,42 @@ /* Run the benchmark for this many ms */ #define TIME 5000 - typedef struct { - int pongs; int state; + int pongs; uv_tcp_t tcp; uv_connect_t connect_req; uv_shutdown_t shutdown_req; + int64_t start_time; + struct buf_s* buf_freelist; + int shutdown_cb_called; + int* completed_pingers; } pinger_t; typedef struct buf_s { uv_buf_t uv_buf_t; struct buf_s* next; + pinger_t* pinger; } buf_t; - static char PING[] = "PING\n"; - static uv_loop_t* loop; -static buf_t* buf_freelist = NULL; -static int pinger_shutdown_cb_called; -static int completed_pingers = 0; -static int64_t start_time; - - static void buf_alloc(uv_handle_t* tcp, size_t size, uv_buf_t* buf) { + pinger_t* pinger; buf_t* ab; - ab = buf_freelist; - if (ab != NULL) - buf_freelist = ab->next; - else { - ab = malloc(size + sizeof(*ab)); + pinger = (pinger_t*)tcp->data; + ab = pinger->buf_freelist; + if (ab != NULL) { + pinger->buf_freelist = ab->next; + ab->next = NULL; + } else { + ab = malloc(sizeof(*ab) + size); ab->uv_buf_t.len = size; ab->uv_buf_t.base = (char*) (ab + 1); + ab->next = NULL; + ab->pinger = pinger; } *buf = ab->uv_buf_t; @@ -71,21 +72,26 @@ static void buf_alloc(uv_handle_t* tcp, size_t size, uv_buf_t* buf) { static void buf_free(const uv_buf_t* buf) { buf_t* ab = (buf_t*) buf->base - 1; - ab->next = buf_freelist; - buf_freelist = ab; + pinger_t* pinger = ab->pinger; + ab->next = pinger->buf_freelist; + pinger->buf_freelist = ab; } static void pinger_close_cb(uv_handle_t* handle) { pinger_t* pinger; + buf_t* next; + buf_t* ab; pinger = (pinger_t*)handle->data; - fprintf(stderr, "ping_pongs: %d roundtrips/s\n", (1000 * pinger->pongs) / TIME); - fflush(stderr); + (*pinger->completed_pingers)++; - free(pinger); - - completed_pingers++; + ab = pinger->buf_freelist; + while (ab != NULL) { + next = ab->next; + free(ab); + ab = next; + } } @@ -110,20 +116,17 @@ static void pinger_write_ping(pinger_t* pinger) { static void pinger_shutdown_cb(uv_shutdown_t* req, int status) { + pinger_t* pinger; ASSERT_OK(status); - pinger_shutdown_cb_called++; - - /* - * The close callback has not been triggered yet. We must wait for EOF - * until we close the connection. - */ - ASSERT_OK(completed_pingers); + pinger = (pinger_t*)req->data; + pinger->shutdown_cb_called++; } static void pinger_read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { + int64_t now; ssize_t i; pinger_t* pinger; @@ -136,7 +139,7 @@ static void pinger_read_cb(uv_stream_t* tcp, buf_free(buf); } - ASSERT_EQ(1, pinger_shutdown_cb_called); + ASSERT_EQ(1, pinger->shutdown_cb_called); uv_close((uv_handle_t*)tcp, pinger_close_cb); return; @@ -147,8 +150,13 @@ static void pinger_read_cb(uv_stream_t* tcp, ASSERT_EQ(buf->base[i], PING[pinger->state]); pinger->state = (pinger->state + 1) % (sizeof(PING) - 1); if (pinger->state == 0) { + now = uv_now(loop); + if (pinger->pongs == 0) { + pinger->start_time = now; + } pinger->pongs++; - if (uv_now(loop) - start_time > TIME) { + if (now - pinger->start_time > TIME) { + pinger->shutdown_req.data = pinger; uv_shutdown(&pinger->shutdown_req, (uv_stream_t*) tcp, pinger_shutdown_cb); @@ -176,19 +184,20 @@ static void pinger_connect_cb(uv_connect_t* req, int status) { } -static void pinger_new(void) { +static void pinger_init(pinger_t* pinger, int* completed_pingers) { struct sockaddr_in client_addr; struct sockaddr_in server_addr; - pinger_t *pinger; int r; ASSERT_OK(uv_ip4_addr("0.0.0.0", 0, &client_addr)); ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); - pinger = malloc(sizeof(*pinger)); pinger->state = 0; pinger->pongs = 0; + pinger->start_time = 0; + pinger->buf_freelist = NULL; + pinger->shutdown_cb_called = 0; + pinger->completed_pingers = completed_pingers; - /* Try to connect to the server and do NUM_PINGS ping-pongs. */ r = uv_tcp_init(loop, &pinger->tcp); ASSERT(!r); @@ -206,16 +215,45 @@ static void pinger_new(void) { } -BENCHMARK_IMPL(ping_pongs) { +static void test_ping_pongs(int count) { + int completed_pingers = 0; + pinger_t* pingers; + int i, sum; + loop = uv_default_loop(); - start_time = uv_now(loop); + pingers = malloc(count * sizeof(pinger_t)); + for (i=0; i