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