mirror of https://github.com/lukechilds/node.git
Ben Noordhuis
12 years ago
65 changed files with 948 additions and 592 deletions
@ -0,0 +1,230 @@ |
|||
#!/bin/sh |
|||
|
|||
# Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl> |
|||
# |
|||
# Permission to use, copy, modify, and/or distribute this software for any |
|||
# purpose with or without fee is hereby granted, provided that the above |
|||
# copyright notice and this permission notice appear in all copies. |
|||
# |
|||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
|||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
|||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|||
|
|||
SPARSE=${SPARSE:-sparse} |
|||
|
|||
SPARSE_FLAGS=${SPARSE_FLAGS:-" |
|||
-D__POSIX__ |
|||
-Wsparse-all |
|||
-Wno-do-while |
|||
-Wno-transparent-union |
|||
-Iinclude |
|||
-Iinclude/uv-private |
|||
-Isrc |
|||
"} |
|||
|
|||
SOURCES=" |
|||
include/uv-private/ngx-queue.h |
|||
include/uv-private/tree.h |
|||
include/uv-private/uv-unix.h |
|||
include/uv.h |
|||
src/fs-poll.c |
|||
src/inet.c |
|||
src/unix/async.c |
|||
src/unix/core.c |
|||
src/unix/dl.c |
|||
src/unix/error.c |
|||
src/unix/fs.c |
|||
src/unix/getaddrinfo.c |
|||
src/unix/internal.h |
|||
src/unix/loop-watcher.c |
|||
src/unix/loop.c |
|||
src/unix/pipe.c |
|||
src/unix/poll.c |
|||
src/unix/process.c |
|||
src/unix/signal.c |
|||
src/unix/stream.c |
|||
src/unix/tcp.c |
|||
src/unix/thread.c |
|||
src/unix/threadpool.c |
|||
src/unix/timer.c |
|||
src/unix/tty.c |
|||
src/unix/udp.c |
|||
src/uv-common.c |
|||
src/uv-common.h |
|||
" |
|||
|
|||
TESTS=" |
|||
test/benchmark-async-pummel.c |
|||
test/benchmark-async.c |
|||
test/benchmark-fs-stat.c |
|||
test/benchmark-getaddrinfo.c |
|||
test/benchmark-loop-count.c |
|||
test/benchmark-million-async.c |
|||
test/benchmark-million-timers.c |
|||
test/benchmark-multi-accept.c |
|||
test/benchmark-ping-pongs.c |
|||
test/benchmark-pound.c |
|||
test/benchmark-pump.c |
|||
test/benchmark-sizes.c |
|||
test/benchmark-spawn.c |
|||
test/benchmark-tcp-write-batch.c |
|||
test/benchmark-thread.c |
|||
test/benchmark-udp-pummel.c |
|||
test/blackhole-server.c |
|||
test/dns-server.c |
|||
test/echo-server.c |
|||
test/run-benchmarks.c |
|||
test/run-tests.c |
|||
test/runner-unix.c |
|||
test/runner-unix.h |
|||
test/runner.c |
|||
test/runner.h |
|||
test/task.h |
|||
test/test-active.c |
|||
test/test-async.c |
|||
test/test-barrier.c |
|||
test/test-callback-order.c |
|||
test/test-callback-stack.c |
|||
test/test-condvar.c |
|||
test/test-connection-fail.c |
|||
test/test-cwd-and-chdir.c |
|||
test/test-delayed-accept.c |
|||
test/test-dlerror.c |
|||
test/test-embed.c |
|||
test/test-error.c |
|||
test/test-fail-always.c |
|||
test/test-fs-event.c |
|||
test/test-fs-poll.c |
|||
test/test-fs.c |
|||
test/test-get-currentexe.c |
|||
test/test-get-loadavg.c |
|||
test/test-get-memory.c |
|||
test/test-getaddrinfo.c |
|||
test/test-getsockname.c |
|||
test/test-hrtime.c |
|||
test/test-idle.c |
|||
test/test-ipc-send-recv.c |
|||
test/test-ipc.c |
|||
test/test-loop-handles.c |
|||
test/test-multiple-listen.c |
|||
test/test-mutexes.c |
|||
test/test-pass-always.c |
|||
test/test-ping-pong.c |
|||
test/test-pipe-bind-error.c |
|||
test/test-pipe-connect-error.c |
|||
test/test-platform-output.c |
|||
test/test-poll-close.c |
|||
test/test-poll.c |
|||
test/test-process-title.c |
|||
test/test-ref.c |
|||
test/test-run-nowait.c |
|||
test/test-run-once.c |
|||
test/test-semaphore.c |
|||
test/test-shutdown-close.c |
|||
test/test-shutdown-eof.c |
|||
test/test-signal-multiple-loops.c |
|||
test/test-signal.c |
|||
test/test-spawn.c |
|||
test/test-stdio-over-pipes.c |
|||
test/test-tcp-bind-error.c |
|||
test/test-tcp-bind6-error.c |
|||
test/test-tcp-close-while-connecting.c |
|||
test/test-tcp-close.c |
|||
test/test-tcp-connect-error-after-write.c |
|||
test/test-tcp-connect-error.c |
|||
test/test-tcp-connect-timeout.c |
|||
test/test-tcp-connect6-error.c |
|||
test/test-tcp-flags.c |
|||
test/test-tcp-open.c |
|||
test/test-tcp-read-stop.c |
|||
test/test-tcp-shutdown-after-write.c |
|||
test/test-tcp-unexpected-read.c |
|||
test/test-tcp-write-error.c |
|||
test/test-tcp-write-to-half-open-connection.c |
|||
test/test-tcp-writealot.c |
|||
test/test-thread.c |
|||
test/test-threadpool-cancel.c |
|||
test/test-threadpool.c |
|||
test/test-timer-again.c |
|||
test/test-timer.c |
|||
test/test-tty.c |
|||
test/test-udp-dgram-too-big.c |
|||
test/test-udp-ipv6.c |
|||
test/test-udp-multicast-join.c |
|||
test/test-udp-multicast-ttl.c |
|||
test/test-udp-open.c |
|||
test/test-udp-options.c |
|||
test/test-udp-send-and-recv.c |
|||
test/test-util.c |
|||
test/test-walk-handles.c |
|||
" |
|||
|
|||
case `uname -s` in |
|||
AIX) |
|||
SPARSE_FLAGS="$SPARSE_FLAGS -D_AIX=1" |
|||
SOURCES="$SOURCES |
|||
src/unix/aix.c" |
|||
;; |
|||
Darwin) |
|||
SPARSE_FLAGS="$SPARSE_FLAGS -D__APPLE__=1" |
|||
SOURCES="$SOURCES |
|||
include/uv-private/uv-bsd.h |
|||
src/unix/darwin.c |
|||
src/unix/kqueue.c |
|||
src/unix/fsevents.c" |
|||
;; |
|||
DragonFly) |
|||
SPARSE_FLAGS="$SPARSE_FLAGS -D__DragonFly__=1" |
|||
SOURCES="$SOURCES |
|||
include/uv-private/uv-bsd.h |
|||
src/unix/kqueue.c |
|||
src/unix/freebsd.c" |
|||
;; |
|||
FreeBSD) |
|||
SPARSE_FLAGS="$SPARSE_FLAGS -D__FreeBSD__=1" |
|||
SOURCES="$SOURCES |
|||
include/uv-private/uv-bsd.h |
|||
src/unix/kqueue.c |
|||
src/unix/freebsd.c" |
|||
;; |
|||
Linux) |
|||
SPARSE_FLAGS="$SPARSE_FLAGS -D__linux__=1" |
|||
SOURCES="$SOURCES |
|||
include/uv-private/uv-linux.h |
|||
src/unix/linux/inotify.c |
|||
src/unix/linux/linux-core.c |
|||
src/unix/linux/syscalls.c |
|||
src/unix/linux/syscalls.h" |
|||
;; |
|||
NetBSD) |
|||
SPARSE_FLAGS="$SPARSE_FLAGS -D__NetBSD__=1" |
|||
SOURCES="$SOURCES |
|||
include/uv-private/uv-bsd.h |
|||
src/unix/kqueue.c |
|||
src/unix/netbsd.c" |
|||
;; |
|||
OpenBSD) |
|||
SPARSE_FLAGS="$SPARSE_FLAGS -D__OpenBSD__=1" |
|||
SOURCES="$SOURCES |
|||
include/uv-private/uv-bsd.h |
|||
src/unix/kqueue.c |
|||
src/unix/openbsd.c" |
|||
;; |
|||
SunOS) |
|||
SPARSE_FLAGS="$SPARSE_FLAGS -D__sun=1" |
|||
SOURCES="$SOURCES |
|||
include/uv-private/uv-sunos.h |
|||
src/unix/sunos.c" |
|||
;; |
|||
esac |
|||
|
|||
for ARCH in __i386__ __x86_64__ __arm__; do |
|||
$SPARSE $SPARSE_FLAGS -D$ARCH=1 $SOURCES |
|||
done |
|||
|
|||
# Tests are architecture independent. |
|||
$SPARSE $SPARSE_FLAGS -Itest $TESTS |
@ -0,0 +1,112 @@ |
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|||
* |
|||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
* of this software and associated documentation files (the "Software"), to |
|||
* deal in the Software without restriction, including without limitation the |
|||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
|||
* sell copies of the Software, and to permit persons to whom the Software is |
|||
* furnished to do so, subject to the following conditions: |
|||
* |
|||
* The above copyright notice and this permission notice shall be included in |
|||
* all copies or substantial portions of the Software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
|||
* IN THE SOFTWARE. |
|||
*/ |
|||
|
|||
#include "task.h" |
|||
#include "uv.h" |
|||
|
|||
struct async_container { |
|||
unsigned async_events; |
|||
unsigned handles_seen; |
|||
uv_async_t async_handles[1024 * 1024]; |
|||
}; |
|||
|
|||
static volatile int done; |
|||
static uv_thread_t thread_id; |
|||
static struct async_container* container; |
|||
|
|||
|
|||
static unsigned fastrand(void) { |
|||
static unsigned g = 0; |
|||
g = g * 214013 + 2531011; |
|||
return g; |
|||
} |
|||
|
|||
|
|||
static void thread_cb(void* arg) { |
|||
unsigned i; |
|||
|
|||
while (done == 0) { |
|||
i = fastrand() % ARRAY_SIZE(container->async_handles); |
|||
uv_async_send(container->async_handles + i); |
|||
} |
|||
} |
|||
|
|||
|
|||
static void async_cb(uv_async_t* handle, int status) { |
|||
container->async_events++; |
|||
handle->data = handle; |
|||
} |
|||
|
|||
|
|||
static void timer_cb(uv_timer_t* handle, int status) { |
|||
unsigned i; |
|||
|
|||
done = 1; |
|||
ASSERT(0 == uv_thread_join(&thread_id)); |
|||
|
|||
for (i = 0; i < ARRAY_SIZE(container->async_handles); i++) { |
|||
uv_async_t* handle = container->async_handles + i; |
|||
|
|||
if (handle->data != NULL) |
|||
container->handles_seen++; |
|||
|
|||
uv_close((uv_handle_t*) handle, NULL); |
|||
} |
|||
|
|||
uv_close((uv_handle_t*) handle, NULL); |
|||
} |
|||
|
|||
|
|||
BENCHMARK_IMPL(million_async) { |
|||
uv_timer_t timer_handle; |
|||
uv_async_t* handle; |
|||
uv_loop_t* loop; |
|||
int timeout; |
|||
unsigned i; |
|||
|
|||
loop = uv_default_loop(); |
|||
timeout = 5000; |
|||
|
|||
container = malloc(sizeof(*container)); |
|||
ASSERT(container != NULL); |
|||
container->async_events = 0; |
|||
container->handles_seen = 0; |
|||
|
|||
for (i = 0; i < ARRAY_SIZE(container->async_handles); i++) { |
|||
handle = container->async_handles + i; |
|||
ASSERT(0 == uv_async_init(loop, handle, async_cb)); |
|||
handle->data = NULL; |
|||
} |
|||
|
|||
ASSERT(0 == uv_timer_init(loop, &timer_handle)); |
|||
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, timeout, 0)); |
|||
ASSERT(0 == uv_thread_create(&thread_id, thread_cb, NULL)); |
|||
ASSERT(0 == uv_run(loop)); |
|||
printf("%s async events in %.1f seconds (%s/s, %s unique handles seen)\n", |
|||
fmt(container->async_events), |
|||
timeout / 1000., |
|||
fmt(container->async_events / (timeout / 1000.)), |
|||
fmt(container->handles_seen)); |
|||
free(container); |
|||
|
|||
MAKE_VALGRIND_HAPPY(); |
|||
return 0; |
|||
} |
@ -1,138 +0,0 @@ |
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|||
* |
|||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
* of this software and associated documentation files (the "Software"), to |
|||
* deal in the Software without restriction, including without limitation the |
|||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
|||
* sell copies of the Software, and to permit persons to whom the Software is |
|||
* furnished to do so, subject to the following conditions: |
|||
* |
|||
* The above copyright notice and this permission notice shall be included in |
|||
* all copies or substantial portions of the Software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
|||
* IN THE SOFTWARE. |
|||
*/ |
|||
|
|||
#include "uv.h" |
|||
#include "task.h" |
|||
|
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
|
|||
#define MAX_CONSUMERS 32 |
|||
#define MAX_LOOPS 1000 |
|||
|
|||
struct buffer_s { |
|||
ngx_queue_t queue; |
|||
int data; |
|||
}; |
|||
typedef struct buffer_s buffer_t; |
|||
|
|||
static ngx_queue_t queue; |
|||
static uv_mutex_t mutex; |
|||
static uv_cond_t empty; |
|||
static uv_cond_t full; |
|||
|
|||
static volatile int finished_consumers = 0; |
|||
|
|||
|
|||
static void produce(int value) { |
|||
buffer_t* buf; |
|||
|
|||
buf = malloc(sizeof(*buf)); |
|||
ngx_queue_init(&buf->queue); |
|||
buf->data = value; |
|||
ngx_queue_insert_tail(&queue, &buf->queue); |
|||
} |
|||
|
|||
|
|||
static int consume(void) { |
|||
ngx_queue_t* q; |
|||
buffer_t* buf; |
|||
int data; |
|||
|
|||
ASSERT(!ngx_queue_empty(&queue)); |
|||
q = ngx_queue_last(&queue); |
|||
ngx_queue_remove(q); |
|||
|
|||
buf = ngx_queue_data(q, buffer_t, queue); |
|||
data = buf->data; |
|||
free(buf); |
|||
|
|||
return data; |
|||
} |
|||
|
|||
|
|||
static void producer(void* arg) { |
|||
int i; |
|||
|
|||
(void) arg; |
|||
|
|||
for (i = 0; i < MAX_LOOPS * MAX_CONSUMERS; i++) { |
|||
uv_mutex_lock(&mutex); |
|||
while(!ngx_queue_empty(&queue)) |
|||
uv_cond_wait(&empty, &mutex); |
|||
produce(i); |
|||
uv_cond_signal(&full); |
|||
uv_mutex_unlock(&mutex); |
|||
} |
|||
} |
|||
|
|||
|
|||
static void consumer(void* arg) { |
|||
int i; |
|||
int value; |
|||
|
|||
(void) arg; |
|||
|
|||
for (i = 0; i < MAX_LOOPS; i++) { |
|||
uv_mutex_lock(&mutex); |
|||
while (ngx_queue_empty(&queue)) |
|||
uv_cond_wait(&full, &mutex); |
|||
value = consume(); |
|||
ASSERT(value < MAX_LOOPS * MAX_CONSUMERS); |
|||
uv_cond_signal(&empty); |
|||
uv_mutex_unlock(&mutex); |
|||
} |
|||
|
|||
finished_consumers++; |
|||
} |
|||
|
|||
|
|||
TEST_IMPL(consumer_producer) { |
|||
int i; |
|||
uv_thread_t cthreads[MAX_CONSUMERS]; |
|||
uv_thread_t pthread; |
|||
|
|||
ngx_queue_init(&queue); |
|||
ASSERT(0 == uv_mutex_init(&mutex)); |
|||
ASSERT(0 == uv_cond_init(&empty)); |
|||
ASSERT(0 == uv_cond_init(&full)); |
|||
|
|||
for (i = 0; i < MAX_CONSUMERS; i++) { |
|||
ASSERT(0 == uv_thread_create(&cthreads[i], consumer, NULL)); |
|||
} |
|||
|
|||
ASSERT(0 == uv_thread_create(&pthread, producer, NULL)); |
|||
|
|||
for (i = 0; i < MAX_CONSUMERS; i++) { |
|||
ASSERT(0 == uv_thread_join(&cthreads[i])); |
|||
} |
|||
|
|||
ASSERT(0 == uv_thread_join(&pthread)); |
|||
|
|||
LOGF("finished_consumers: %d\n", finished_consumers); |
|||
ASSERT(finished_consumers == MAX_CONSUMERS); |
|||
|
|||
uv_cond_destroy(&empty); |
|||
uv_cond_destroy(&full); |
|||
uv_mutex_destroy(&mutex); |
|||
|
|||
return 0; |
|||
} |
@ -0,0 +1,46 @@ |
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|||
* |
|||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
* of this software and associated documentation files (the "Software"), to |
|||
* deal in the Software without restriction, including without limitation the |
|||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
|||
* sell copies of the Software, and to permit persons to whom the Software is |
|||
* furnished to do so, subject to the following conditions: |
|||
* |
|||
* The above copyright notice and this permission notice shall be included in |
|||
* all copies or substantial portions of the Software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
|||
* IN THE SOFTWARE. |
|||
*/ |
|||
|
|||
#include "uv.h" |
|||
#include "task.h" |
|||
|
|||
static uv_timer_t timer_handle; |
|||
static int timer_called = 0; |
|||
|
|||
|
|||
static void timer_cb(uv_timer_t* handle, int status) { |
|||
ASSERT(handle == &timer_handle); |
|||
ASSERT(status == 0); |
|||
timer_called = 1; |
|||
} |
|||
|
|||
|
|||
TEST_IMPL(run_nowait) { |
|||
int r; |
|||
uv_timer_init(uv_default_loop(), &timer_handle); |
|||
uv_timer_start(&timer_handle, timer_cb, 100, 100); |
|||
|
|||
r = uv_run2(uv_default_loop(), UV_RUN_NOWAIT); |
|||
ASSERT(r != 0); |
|||
ASSERT(timer_called == 0); |
|||
|
|||
return 0; |
|||
} |
Loading…
Reference in new issue