libuv-svace-build
164 строки · 3.9 Кб
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/* This benchmark spawns itself 1000 times. */
23
24#include "task.h"25#include "uv.h"26
27static uv_loop_t* loop;28
29static int N = 1000;30static int done;31
32static uv_process_t process;33static uv_process_options_t options;34static char exepath[1024];35static size_t exepath_size = 1024;36static char* args[3];37static uv_pipe_t out;38
39#define OUTPUT_SIZE 102440static char output[OUTPUT_SIZE];41static int output_used;42
43static int process_open;44static int pipe_open;45
46
47static void spawn(void);48
49
50static void maybe_spawn(void) {51if (process_open == 0 && pipe_open == 0) {52done++;53if (done < N) {54spawn();55}56}57}
58
59
60static void process_close_cb(uv_handle_t* handle) {61ASSERT_EQ(1, process_open);62process_open = 0;63maybe_spawn();64}
65
66
67static void exit_cb(uv_process_t* process,68int64_t exit_status,69int term_signal) {70ASSERT_EQ(42, exit_status);71ASSERT_OK(term_signal);72uv_close((uv_handle_t*)process, process_close_cb);73}
74
75
76static void on_alloc(uv_handle_t* handle,77size_t suggested_size,78uv_buf_t* buf) {79buf->base = output + output_used;80buf->len = OUTPUT_SIZE - output_used;81}
82
83
84static void pipe_close_cb(uv_handle_t* pipe) {85ASSERT_EQ(1, pipe_open);86pipe_open = 0;87maybe_spawn();88}
89
90
91static void on_read(uv_stream_t* pipe, ssize_t nread, const uv_buf_t* buf) {92if (nread > 0) {93ASSERT_EQ(1, pipe_open);94output_used += nread;95} else if (nread < 0) {96if (nread == UV_EOF) {97uv_close((uv_handle_t*)pipe, pipe_close_cb);98}99}100}
101
102
103static void spawn(void) {104uv_stdio_container_t stdio[2];105int r;106
107ASSERT_OK(process_open);108ASSERT_OK(pipe_open);109
110args[0] = exepath;111args[1] = "spawn_helper";112args[2] = NULL;113options.file = exepath;114options.args = args;115options.exit_cb = exit_cb;116
117uv_pipe_init(loop, &out, 0);118
119options.stdio = stdio;120options.stdio_count = 2;121options.stdio[0].flags = UV_IGNORE;122options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;123options.stdio[1].data.stream = (uv_stream_t*)&out;124
125r = uv_spawn(loop, &process, &options);126ASSERT_OK(r);127
128process_open = 1;129pipe_open = 1;130output_used = 0;131
132r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);133ASSERT_OK(r);134}
135
136
137BENCHMARK_IMPL(spawn) {138int r;139static int64_t start_time, end_time;140
141loop = uv_default_loop();142
143r = uv_exepath(exepath, &exepath_size);144ASSERT_OK(r);145exepath[exepath_size] = '\0';146
147uv_update_time(loop);148start_time = uv_now(loop);149
150spawn();151
152r = uv_run(loop, UV_RUN_DEFAULT);153ASSERT_OK(r);154
155uv_update_time(loop);156end_time = uv_now(loop);157
158fprintf(stderr, "spawn: %.0f spawns/s\n",159(double) N / (double) (end_time - start_time) * 1000.0);160fflush(stderr);161
162MAKE_VALGRIND_HAPPY(loop);163return 0;164}
165