Home | History | Annotate | Line # | Download | only in test
benchmark-tcp-write-batch.c revision 1.1
      1  1.1  christos /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
      2  1.1  christos  *
      3  1.1  christos  * Permission is hereby granted, free of charge, to any person obtaining a copy
      4  1.1  christos  * of this software and associated documentation files (the "Software"), to
      5  1.1  christos  * deal in the Software without restriction, including without limitation the
      6  1.1  christos  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
      7  1.1  christos  * sell copies of the Software, and to permit persons to whom the Software is
      8  1.1  christos  * furnished to do so, subject to the following conditions:
      9  1.1  christos  *
     10  1.1  christos  * The above copyright notice and this permission notice shall be included in
     11  1.1  christos  * all copies or substantial portions of the Software.
     12  1.1  christos  *
     13  1.1  christos  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     14  1.1  christos  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     15  1.1  christos  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     16  1.1  christos  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     17  1.1  christos  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     18  1.1  christos  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     19  1.1  christos  * IN THE SOFTWARE.
     20  1.1  christos  */
     21  1.1  christos 
     22  1.1  christos #include "uv.h"
     23  1.1  christos #include "task.h"
     24  1.1  christos 
     25  1.1  christos #include <stdio.h>
     26  1.1  christos #include <stdlib.h>
     27  1.1  christos 
     28  1.1  christos #define WRITE_REQ_DATA  "Hello, world."
     29  1.1  christos #define NUM_WRITE_REQS  (1000 * 1000)
     30  1.1  christos 
     31  1.1  christos typedef struct {
     32  1.1  christos   uv_write_t req;
     33  1.1  christos   uv_buf_t buf;
     34  1.1  christos } write_req;
     35  1.1  christos 
     36  1.1  christos 
     37  1.1  christos static write_req* write_reqs;
     38  1.1  christos static uv_tcp_t tcp_client;
     39  1.1  christos static uv_connect_t connect_req;
     40  1.1  christos static uv_shutdown_t shutdown_req;
     41  1.1  christos 
     42  1.1  christos static int shutdown_cb_called = 0;
     43  1.1  christos static int connect_cb_called = 0;
     44  1.1  christos static int write_cb_called = 0;
     45  1.1  christos static int close_cb_called = 0;
     46  1.1  christos 
     47  1.1  christos static void connect_cb(uv_connect_t* req, int status);
     48  1.1  christos static void write_cb(uv_write_t* req, int status);
     49  1.1  christos static void shutdown_cb(uv_shutdown_t* req, int status);
     50  1.1  christos static void close_cb(uv_handle_t* handle);
     51  1.1  christos 
     52  1.1  christos 
     53  1.1  christos static void connect_cb(uv_connect_t* req, int status) {
     54  1.1  christos   write_req* w;
     55  1.1  christos   int i;
     56  1.1  christos   int r;
     57  1.1  christos 
     58  1.1  christos   ASSERT(req->handle == (uv_stream_t*)&tcp_client);
     59  1.1  christos 
     60  1.1  christos   for (i = 0; i < NUM_WRITE_REQS; i++) {
     61  1.1  christos     w = &write_reqs[i];
     62  1.1  christos     r = uv_write(&w->req, req->handle, &w->buf, 1, write_cb);
     63  1.1  christos     ASSERT(r == 0);
     64  1.1  christos   }
     65  1.1  christos 
     66  1.1  christos   r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
     67  1.1  christos   ASSERT(r == 0);
     68  1.1  christos 
     69  1.1  christos   connect_cb_called++;
     70  1.1  christos }
     71  1.1  christos 
     72  1.1  christos 
     73  1.1  christos static void write_cb(uv_write_t* req, int status) {
     74  1.1  christos   ASSERT(req != NULL);
     75  1.1  christos   ASSERT(status == 0);
     76  1.1  christos   write_cb_called++;
     77  1.1  christos }
     78  1.1  christos 
     79  1.1  christos 
     80  1.1  christos static void shutdown_cb(uv_shutdown_t* req, int status) {
     81  1.1  christos   ASSERT(req->handle == (uv_stream_t*)&tcp_client);
     82  1.1  christos   ASSERT(req->handle->write_queue_size == 0);
     83  1.1  christos 
     84  1.1  christos   uv_close((uv_handle_t*)req->handle, close_cb);
     85  1.1  christos   free(write_reqs);
     86  1.1  christos 
     87  1.1  christos   shutdown_cb_called++;
     88  1.1  christos }
     89  1.1  christos 
     90  1.1  christos 
     91  1.1  christos static void close_cb(uv_handle_t* handle) {
     92  1.1  christos   ASSERT(handle == (uv_handle_t*)&tcp_client);
     93  1.1  christos   close_cb_called++;
     94  1.1  christos }
     95  1.1  christos 
     96  1.1  christos 
     97  1.1  christos BENCHMARK_IMPL(tcp_write_batch) {
     98  1.1  christos   struct sockaddr_in addr;
     99  1.1  christos   uv_loop_t* loop;
    100  1.1  christos   uint64_t start;
    101  1.1  christos   uint64_t stop;
    102  1.1  christos   int i;
    103  1.1  christos   int r;
    104  1.1  christos 
    105  1.1  christos   write_reqs = malloc(sizeof(*write_reqs) * NUM_WRITE_REQS);
    106  1.1  christos   ASSERT(write_reqs != NULL);
    107  1.1  christos 
    108  1.1  christos   /* Prepare the data to write out. */
    109  1.1  christos   for (i = 0; i < NUM_WRITE_REQS; i++) {
    110  1.1  christos     write_reqs[i].buf = uv_buf_init(WRITE_REQ_DATA,
    111  1.1  christos                                     sizeof(WRITE_REQ_DATA) - 1);
    112  1.1  christos   }
    113  1.1  christos 
    114  1.1  christos   loop = uv_default_loop();
    115  1.1  christos   ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
    116  1.1  christos 
    117  1.1  christos   r = uv_tcp_init(loop, &tcp_client);
    118  1.1  christos   ASSERT(r == 0);
    119  1.1  christos 
    120  1.1  christos   r = uv_tcp_connect(&connect_req,
    121  1.1  christos                      &tcp_client,
    122  1.1  christos                      (const struct sockaddr*) &addr,
    123  1.1  christos                      connect_cb);
    124  1.1  christos   ASSERT(r == 0);
    125  1.1  christos 
    126  1.1  christos   start = uv_hrtime();
    127  1.1  christos 
    128  1.1  christos   r = uv_run(loop, UV_RUN_DEFAULT);
    129  1.1  christos   ASSERT(r == 0);
    130  1.1  christos 
    131  1.1  christos   stop = uv_hrtime();
    132  1.1  christos 
    133  1.1  christos   ASSERT(connect_cb_called == 1);
    134  1.1  christos   ASSERT(write_cb_called == NUM_WRITE_REQS);
    135  1.1  christos   ASSERT(shutdown_cb_called == 1);
    136  1.1  christos   ASSERT(close_cb_called == 1);
    137  1.1  christos 
    138  1.1  christos   printf("%ld write requests in %.2fs.\n",
    139  1.1  christos          (long)NUM_WRITE_REQS,
    140  1.1  christos          (stop - start) / 1e9);
    141  1.1  christos 
    142  1.1  christos   MAKE_VALGRIND_HAPPY();
    143  1.1  christos   return 0;
    144  1.1  christos }
    145