asyncengine 0.0.1.testing1 → 0.0.2.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +3 -0
- data/Rakefile +38 -0
- data/asyncengine.gemspec +8 -4
- data/ext/asyncengine/ae_call_from_other_thread.c +106 -0
- data/ext/asyncengine/ae_call_from_other_thread.h +12 -0
- data/ext/asyncengine/ae_handle_common.c +193 -48
- data/ext/asyncengine/ae_handle_common.h +40 -13
- data/ext/asyncengine/ae_ip_utils.c +246 -0
- data/ext/asyncengine/ae_ip_utils.h +25 -0
- data/ext/asyncengine/ae_next_tick.c +81 -21
- data/ext/asyncengine/ae_next_tick.h +4 -2
- data/ext/asyncengine/ae_resolver.c +156 -0
- data/ext/asyncengine/ae_resolver.h +10 -0
- data/ext/asyncengine/ae_tcp.c +908 -0
- data/ext/asyncengine/ae_tcp.h +20 -0
- data/ext/asyncengine/ae_timer.c +355 -81
- data/ext/asyncengine/ae_timer.h +11 -4
- data/ext/asyncengine/ae_udp.c +579 -13
- data/ext/asyncengine/ae_udp.h +15 -2
- data/ext/asyncengine/ae_utils.c +192 -0
- data/ext/asyncengine/ae_utils.h +16 -0
- data/ext/asyncengine/asyncengine_ruby.c +469 -26
- data/ext/asyncengine/asyncengine_ruby.h +49 -11
- data/ext/asyncengine/debug.h +68 -0
- data/ext/asyncengine/extconf.rb +26 -2
- data/ext/asyncengine/ip_parser.c +5954 -0
- data/ext/asyncengine/ip_parser.h +16 -0
- data/ext/asyncengine/libuv/AUTHORS +16 -0
- data/ext/asyncengine/libuv/common.gypi +4 -4
- data/ext/asyncengine/libuv/config-mingw.mk +6 -6
- data/ext/asyncengine/libuv/config-unix.mk +13 -13
- data/ext/asyncengine/libuv/gyp_uv +5 -1
- data/ext/asyncengine/libuv/ibc_tests/exec_test.sh +8 -0
- data/ext/asyncengine/libuv/ibc_tests/uv_shutdown_write_issue.c +171 -0
- data/ext/asyncengine/libuv/ibc_tests/uv_tcp_close_while_connecting.c +102 -0
- data/ext/asyncengine/libuv/include/uv-private/ngx-queue.h +3 -1
- data/ext/asyncengine/libuv/include/uv-private/uv-unix.h +103 -50
- data/ext/asyncengine/libuv/include/uv-private/uv-win.h +76 -24
- data/ext/asyncengine/libuv/include/uv.h +353 -88
- data/ext/asyncengine/libuv/src/ares/ares__close_sockets.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares__get_hostent.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares__read_line.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares__timeval.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_cancel.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_data.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_destroy.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_expand_name.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_expand_string.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_fds.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_free_hostent.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_free_string.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_gethostbyaddr.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_gethostbyname.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_getnameinfo.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_getopt.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_getsock.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_init.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_library_init.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_llist.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_mkquery.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_nowarn.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_options.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_a_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_aaaa_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_mx_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_ns_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_ptr_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_srv_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_txt_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_process.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_query.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_search.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_send.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_strcasecmp.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_strdup.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_strerror.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_timeout.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_version.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_writev.o +0 -0
- data/ext/asyncengine/libuv/src/ares/bitncmp.o +0 -0
- data/ext/asyncengine/libuv/src/ares/inet_net_pton.o +0 -0
- data/ext/asyncengine/libuv/src/ares/inet_ntop.o +0 -0
- data/ext/asyncengine/libuv/src/cares.c +225 -0
- data/ext/asyncengine/libuv/src/cares.o +0 -0
- data/ext/asyncengine/libuv/src/fs-poll.c +237 -0
- data/ext/asyncengine/libuv/src/fs-poll.o +0 -0
- data/ext/asyncengine/libuv/src/unix/async.c +78 -17
- data/ext/asyncengine/libuv/src/unix/async.o +0 -0
- data/ext/asyncengine/libuv/src/unix/core.c +305 -213
- data/ext/asyncengine/libuv/src/unix/core.o +0 -0
- data/ext/asyncengine/libuv/src/unix/cygwin.c +1 -1
- data/ext/asyncengine/libuv/src/unix/darwin.c +2 -1
- data/ext/asyncengine/libuv/src/unix/dl.c +36 -44
- data/ext/asyncengine/libuv/src/unix/dl.o +0 -0
- data/ext/asyncengine/libuv/src/unix/eio/eio.o +0 -0
- data/ext/asyncengine/libuv/src/unix/error.c +6 -0
- data/ext/asyncengine/libuv/src/unix/error.o +0 -0
- data/ext/asyncengine/libuv/src/unix/ev/ev.c +8 -4
- data/ext/asyncengine/libuv/src/unix/ev/ev.o +0 -0
- data/ext/asyncengine/libuv/src/unix/freebsd.c +1 -1
- data/ext/asyncengine/libuv/src/unix/fs.c +25 -33
- data/ext/asyncengine/libuv/src/unix/fs.o +0 -0
- data/ext/asyncengine/libuv/src/unix/internal.h +50 -31
- data/ext/asyncengine/libuv/src/unix/kqueue.c +2 -7
- data/ext/asyncengine/libuv/src/unix/linux/core.o +0 -0
- data/ext/asyncengine/libuv/src/unix/linux/inotify.c +12 -14
- data/ext/asyncengine/libuv/src/unix/linux/inotify.o +0 -0
- data/ext/asyncengine/libuv/src/unix/linux/{core.c → linux-core.c} +1 -1
- data/ext/asyncengine/libuv/src/unix/linux/linux-core.o +0 -0
- data/ext/asyncengine/libuv/src/unix/linux/syscalls.c +147 -1
- data/ext/asyncengine/libuv/src/unix/linux/syscalls.h +39 -2
- data/ext/asyncengine/libuv/src/unix/linux/syscalls.o +0 -0
- data/ext/asyncengine/libuv/src/unix/loop-watcher.c +63 -0
- data/ext/asyncengine/libuv/src/unix/loop-watcher.o +0 -0
- data/ext/asyncengine/libuv/src/unix/loop.c +29 -6
- data/ext/asyncengine/libuv/src/unix/loop.o +0 -0
- data/ext/asyncengine/libuv/src/unix/netbsd.c +1 -1
- data/ext/asyncengine/libuv/src/unix/openbsd.c +1 -1
- data/ext/asyncengine/libuv/src/unix/pipe.c +31 -36
- data/ext/asyncengine/libuv/src/unix/pipe.o +0 -0
- data/ext/asyncengine/libuv/src/unix/poll.c +116 -0
- data/ext/asyncengine/libuv/src/unix/poll.o +0 -0
- data/ext/asyncengine/libuv/src/unix/process.c +193 -115
- data/ext/asyncengine/libuv/src/unix/process.o +0 -0
- data/ext/asyncengine/libuv/src/unix/stream.c +146 -153
- data/ext/asyncengine/libuv/src/unix/stream.o +0 -0
- data/ext/asyncengine/libuv/src/unix/sunos.c +45 -36
- data/ext/asyncengine/libuv/src/unix/tcp.c +6 -5
- data/ext/asyncengine/libuv/src/unix/tcp.o +0 -0
- data/ext/asyncengine/libuv/src/unix/thread.c +82 -25
- data/ext/asyncengine/libuv/src/unix/thread.o +0 -0
- data/ext/asyncengine/libuv/src/unix/timer.c +69 -58
- data/ext/asyncengine/libuv/src/unix/timer.o +0 -0
- data/ext/asyncengine/libuv/src/unix/tty.c +3 -3
- data/ext/asyncengine/libuv/src/unix/tty.o +0 -0
- data/ext/asyncengine/libuv/src/unix/udp.c +57 -66
- data/ext/asyncengine/libuv/src/unix/udp.o +0 -0
- data/ext/asyncengine/libuv/src/unix/uv-eio.c +33 -50
- data/ext/asyncengine/libuv/src/unix/uv-eio.o +0 -0
- data/ext/asyncengine/libuv/src/uv-common.c +68 -38
- data/ext/asyncengine/libuv/src/uv-common.h +104 -20
- data/ext/asyncengine/libuv/src/uv-common.o +0 -0
- data/ext/asyncengine/libuv/src/win/async.c +20 -17
- data/ext/asyncengine/libuv/src/win/core.c +44 -31
- data/ext/asyncengine/libuv/src/win/dl.c +40 -36
- data/ext/asyncengine/libuv/src/win/error.c +21 -1
- data/ext/asyncengine/libuv/src/win/fs-event.c +19 -21
- data/ext/asyncengine/libuv/src/win/fs.c +541 -189
- data/ext/asyncengine/libuv/src/win/getaddrinfo.c +56 -63
- data/ext/asyncengine/libuv/src/win/handle-inl.h +145 -0
- data/ext/asyncengine/libuv/src/win/handle.c +26 -101
- data/ext/asyncengine/libuv/src/win/internal.h +92 -107
- data/ext/asyncengine/libuv/src/win/loop-watcher.c +6 -14
- data/ext/asyncengine/libuv/src/win/pipe.c +78 -64
- data/ext/asyncengine/libuv/src/win/poll.c +618 -0
- data/ext/asyncengine/libuv/src/win/process-stdio.c +479 -0
- data/ext/asyncengine/libuv/src/win/process.c +147 -274
- data/ext/asyncengine/libuv/src/win/req-inl.h +225 -0
- data/ext/asyncengine/libuv/src/win/req.c +0 -149
- data/ext/asyncengine/libuv/src/{unix/check.c → win/stream-inl.h} +31 -42
- data/ext/asyncengine/libuv/src/win/stream.c +9 -43
- data/ext/asyncengine/libuv/src/win/tcp.c +200 -82
- data/ext/asyncengine/libuv/src/win/thread.c +42 -2
- data/ext/asyncengine/libuv/src/win/threadpool.c +3 -2
- data/ext/asyncengine/libuv/src/win/timer.c +13 -63
- data/ext/asyncengine/libuv/src/win/tty.c +26 -20
- data/ext/asyncengine/libuv/src/win/udp.c +26 -17
- data/ext/asyncengine/libuv/src/win/util.c +312 -167
- data/ext/asyncengine/libuv/src/win/winapi.c +16 -1
- data/ext/asyncengine/libuv/src/win/winapi.h +33 -9
- data/ext/asyncengine/libuv/src/win/winsock.c +88 -1
- data/ext/asyncengine/libuv/src/win/winsock.h +36 -3
- data/ext/asyncengine/libuv/test/benchmark-ares.c +16 -17
- data/ext/asyncengine/libuv/test/benchmark-fs-stat.c +164 -0
- data/ext/asyncengine/libuv/test/benchmark-list.h +9 -0
- data/ext/asyncengine/libuv/{src/unix/prepare.c → test/benchmark-loop-count.c} +42 -33
- data/ext/asyncengine/libuv/test/benchmark-million-timers.c +65 -0
- data/ext/asyncengine/libuv/test/benchmark-pound.c +1 -1
- data/ext/asyncengine/libuv/test/benchmark-sizes.c +2 -0
- data/ext/asyncengine/libuv/test/benchmark-spawn.c +7 -1
- data/ext/asyncengine/libuv/test/benchmark-udp-packet-storm.c +1 -1
- data/ext/asyncengine/libuv/test/echo-server.c +8 -0
- data/ext/asyncengine/libuv/test/run-tests.c +30 -0
- data/ext/asyncengine/libuv/test/runner-unix.c +6 -26
- data/ext/asyncengine/libuv/test/runner-win.c +5 -63
- data/ext/asyncengine/libuv/test/runner.c +10 -1
- data/ext/asyncengine/libuv/test/task.h +0 -8
- data/ext/asyncengine/libuv/test/test-async.c +43 -141
- data/ext/asyncengine/libuv/test/test-callback-order.c +76 -0
- data/ext/asyncengine/libuv/test/test-counters-init.c +2 -3
- data/ext/asyncengine/libuv/test/test-dlerror.c +17 -8
- data/ext/asyncengine/libuv/test/test-fs-event.c +31 -39
- data/ext/asyncengine/libuv/test/test-fs-poll.c +146 -0
- data/ext/asyncengine/libuv/test/test-fs.c +114 -2
- data/ext/asyncengine/libuv/test/test-gethostbyname.c +8 -8
- data/ext/asyncengine/libuv/test/test-hrtime.c +18 -15
- data/ext/asyncengine/libuv/test/test-ipc.c +8 -2
- data/ext/asyncengine/libuv/test/test-list.h +59 -9
- data/ext/asyncengine/libuv/test/test-loop-handles.c +2 -25
- data/ext/asyncengine/libuv/{src/unix/idle.c → test/test-poll-close.c} +37 -39
- data/ext/asyncengine/libuv/test/test-poll.c +573 -0
- data/ext/asyncengine/libuv/test/test-ref.c +79 -63
- data/ext/asyncengine/libuv/test/test-run-once.c +15 -11
- data/ext/asyncengine/libuv/test/test-semaphore.c +111 -0
- data/ext/asyncengine/libuv/test/test-spawn.c +368 -20
- data/ext/asyncengine/libuv/test/test-stdio-over-pipes.c +25 -35
- data/ext/asyncengine/libuv/test/test-tcp-close-while-connecting.c +80 -0
- data/ext/asyncengine/libuv/test/test-tcp-close.c +1 -1
- data/ext/asyncengine/libuv/test/test-tcp-connect-error-after-write.c +95 -0
- data/ext/asyncengine/libuv/test/test-tcp-connect-timeout.c +85 -0
- data/ext/asyncengine/libuv/test/test-tcp-shutdown-after-write.c +131 -0
- data/ext/asyncengine/libuv/test/test-tcp-write-error.c +2 -2
- data/ext/asyncengine/libuv/test/test-tcp-writealot.c +29 -54
- data/ext/asyncengine/libuv/test/test-timer-again.c +1 -1
- data/ext/asyncengine/libuv/test/test-timer.c +23 -1
- data/ext/asyncengine/libuv/test/test-udp-options.c +1 -1
- data/ext/asyncengine/libuv/test/{test-eio-overflow.c → test-walk-handles.c} +31 -44
- data/ext/asyncengine/libuv/uv.gyp +26 -9
- data/ext/asyncengine/rb_utilities.c +54 -0
- data/ext/asyncengine/rb_utilities.h +63 -0
- data/lib/asyncengine.rb +45 -38
- data/lib/asyncengine/asyncengine_ext.so +0 -0
- data/lib/asyncengine/debug.rb +37 -0
- data/lib/asyncengine/handle.rb +9 -0
- data/lib/asyncengine/tcp.rb +28 -0
- data/lib/asyncengine/timer.rb +18 -28
- data/lib/asyncengine/udp.rb +29 -0
- data/lib/asyncengine/utils.rb +32 -0
- data/lib/asyncengine/uv_error.rb +17 -0
- data/lib/asyncengine/version.rb +9 -1
- data/test/ae_test_helper.rb +62 -0
- data/test/test_basic.rb +169 -0
- data/test/test_call_from_other_thread.rb +55 -0
- data/test/test_error.rb +92 -0
- data/test/test_ip_utils.rb +44 -0
- data/test/test_next_tick.rb +37 -0
- data/test/test_resolver.rb +51 -0
- data/test/test_threads.rb +69 -0
- data/test/test_timer.rb +95 -0
- data/test/test_udp.rb +216 -0
- data/test/test_utils.rb +49 -0
- metadata +84 -57
- data/ext/asyncengine/libuv/mkmf.log +0 -24
- data/ext/asyncengine/libuv/src/unix/cares.c +0 -194
- data/ext/asyncengine/libuv/src/unix/cares.o +0 -0
- data/ext/asyncengine/libuv/src/unix/check.o +0 -0
- data/ext/asyncengine/libuv/src/unix/idle.o +0 -0
- data/ext/asyncengine/libuv/src/unix/prepare.o +0 -0
- data/ext/asyncengine/libuv/src/win/cares.c +0 -290
- data/lib/asyncengine/errors.rb +0 -5
- data/lib/asyncengine/next_tick.rb +0 -24
|
@@ -22,17 +22,22 @@
|
|
|
22
22
|
#include <assert.h>
|
|
23
23
|
|
|
24
24
|
#include "uv.h"
|
|
25
|
-
#include "../uv-common.h"
|
|
26
25
|
#include "internal.h"
|
|
27
26
|
|
|
28
27
|
|
|
28
|
+
/* Ntdll function pointers */
|
|
29
29
|
sRtlNtStatusToDosError pRtlNtStatusToDosError;
|
|
30
30
|
sNtDeviceIoControlFile pNtDeviceIoControlFile;
|
|
31
31
|
sNtQueryInformationFile pNtQueryInformationFile;
|
|
32
32
|
sNtSetInformationFile pNtSetInformationFile;
|
|
33
|
+
sNtQuerySystemInformation pNtQuerySystemInformation;
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
/* Kernel32 function pointers */
|
|
33
37
|
sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
|
|
34
38
|
sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
|
|
35
39
|
sCreateSymbolicLinkW pCreateSymbolicLinkW;
|
|
40
|
+
sCancelIoEx pCancelIoEx;
|
|
36
41
|
sInitializeSRWLock pInitializeSRWLock;
|
|
37
42
|
sAcquireSRWLockShared pAcquireSRWLockShared;
|
|
38
43
|
sAcquireSRWLockExclusive pAcquireSRWLockExclusive;
|
|
@@ -79,6 +84,13 @@ void uv_winapi_init() {
|
|
|
79
84
|
uv_fatal_error(GetLastError(), "GetProcAddress");
|
|
80
85
|
}
|
|
81
86
|
|
|
87
|
+
pNtQuerySystemInformation = (sNtQuerySystemInformation) GetProcAddress(
|
|
88
|
+
ntdll_module,
|
|
89
|
+
"NtQuerySystemInformation");
|
|
90
|
+
if (pNtQuerySystemInformation == NULL) {
|
|
91
|
+
uv_fatal_error(GetLastError(), "GetProcAddress");
|
|
92
|
+
}
|
|
93
|
+
|
|
82
94
|
kernel32_module = GetModuleHandleA("kernel32.dll");
|
|
83
95
|
if (kernel32_module == NULL) {
|
|
84
96
|
uv_fatal_error(GetLastError(), "GetModuleHandleA");
|
|
@@ -94,6 +106,9 @@ void uv_winapi_init() {
|
|
|
94
106
|
pCreateSymbolicLinkW = (sCreateSymbolicLinkW)
|
|
95
107
|
GetProcAddress(kernel32_module, "CreateSymbolicLinkW");
|
|
96
108
|
|
|
109
|
+
pCancelIoEx = (sCancelIoEx)
|
|
110
|
+
GetProcAddress(kernel32_module, "CancelIoEx");
|
|
111
|
+
|
|
97
112
|
pInitializeSRWLock = (sInitializeSRWLock)
|
|
98
113
|
GetProcAddress(kernel32_module, "InitializeSRWLock");
|
|
99
114
|
|
|
@@ -28,11 +28,6 @@
|
|
|
28
28
|
/*
|
|
29
29
|
* Ntdll headers
|
|
30
30
|
*/
|
|
31
|
-
#ifndef _NTDEF_
|
|
32
|
-
typedef LONG NTSTATUS;
|
|
33
|
-
typedef NTSTATUS *PNTSTATUS;
|
|
34
|
-
#endif
|
|
35
|
-
|
|
36
31
|
#ifndef STATUS_SEVERITY_SUCCESS
|
|
37
32
|
# define STATUS_SEVERITY_SUCCESS 0x0
|
|
38
33
|
#endif
|
|
@@ -4079,8 +4074,8 @@
|
|
|
4079
4074
|
(FACILITY_NTWIN32 << 16) | ERROR_SEVERITY_WARNING)))
|
|
4080
4075
|
|
|
4081
4076
|
/* from ntifs.h */
|
|
4082
|
-
/* MinGW already has it */
|
|
4083
|
-
#if defined(_MSC_VER) || defined(
|
|
4077
|
+
/* MinGW already has it, mingw-w64 does not. */
|
|
4078
|
+
#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
|
|
4084
4079
|
typedef struct _REPARSE_DATA_BUFFER {
|
|
4085
4080
|
ULONG ReparseTag;
|
|
4086
4081
|
USHORT ReparseDataLength;
|
|
@@ -4141,6 +4136,10 @@ typedef struct _FILE_MODE_INFORMATION {
|
|
|
4141
4136
|
ULONG Mode;
|
|
4142
4137
|
} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION;
|
|
4143
4138
|
|
|
4139
|
+
typedef struct _FILE_END_OF_FILE_INFORMATION {
|
|
4140
|
+
LARGE_INTEGER EndOfFile;
|
|
4141
|
+
} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;
|
|
4142
|
+
|
|
4144
4143
|
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
|
|
4145
4144
|
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
|
|
4146
4145
|
|
|
@@ -4203,6 +4202,19 @@ typedef enum _FILE_INFORMATION_CLASS {
|
|
|
4203
4202
|
FileMaximumInformation
|
|
4204
4203
|
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
|
|
4205
4204
|
|
|
4205
|
+
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
|
|
4206
|
+
LARGE_INTEGER IdleTime;
|
|
4207
|
+
LARGE_INTEGER KernelTime;
|
|
4208
|
+
LARGE_INTEGER UserTime;
|
|
4209
|
+
LARGE_INTEGER DpcTime;
|
|
4210
|
+
LARGE_INTEGER InterruptTime;
|
|
4211
|
+
ULONG InterruptCount;
|
|
4212
|
+
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
|
|
4213
|
+
|
|
4214
|
+
#ifndef SystemProcessorPerformanceInformation
|
|
4215
|
+
# define SystemProcessorPerformanceInformation 8
|
|
4216
|
+
#endif
|
|
4217
|
+
|
|
4206
4218
|
#ifndef DEVICE_TYPE
|
|
4207
4219
|
# define DEVICE_TYPE DWORD
|
|
4208
4220
|
#endif
|
|
@@ -4319,6 +4331,12 @@ typedef NTSTATUS (NTAPI *sNtSetInformationFile)
|
|
|
4319
4331
|
ULONG Length,
|
|
4320
4332
|
FILE_INFORMATION_CLASS FileInformationClass);
|
|
4321
4333
|
|
|
4334
|
+
typedef NTSTATUS (NTAPI *sNtQuerySystemInformation)
|
|
4335
|
+
(UINT SystemInformationClass,
|
|
4336
|
+
PVOID SystemInformation,
|
|
4337
|
+
ULONG SystemInformationLength,
|
|
4338
|
+
PULONG ReturnLength);
|
|
4339
|
+
|
|
4322
4340
|
|
|
4323
4341
|
/*
|
|
4324
4342
|
* Kernel32 headers
|
|
@@ -4335,7 +4353,7 @@ typedef NTSTATUS (NTAPI *sNtSetInformationFile)
|
|
|
4335
4353
|
# define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1
|
|
4336
4354
|
#endif
|
|
4337
4355
|
|
|
4338
|
-
#
|
|
4356
|
+
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
|
|
4339
4357
|
typedef struct _OVERLAPPED_ENTRY {
|
|
4340
4358
|
ULONG_PTR lpCompletionKey;
|
|
4341
4359
|
LPOVERLAPPED lpOverlapped;
|
|
@@ -4374,6 +4392,10 @@ typedef BOOLEAN (WINAPI* sCreateSymbolicLinkW)
|
|
|
4374
4392
|
LPCWSTR lpTargetFileName,
|
|
4375
4393
|
DWORD dwFlags);
|
|
4376
4394
|
|
|
4395
|
+
typedef BOOL (WINAPI* sCancelIoEx)
|
|
4396
|
+
(HANDLE hFile,
|
|
4397
|
+
LPOVERLAPPED lpOverlapped);
|
|
4398
|
+
|
|
4377
4399
|
typedef VOID (WINAPI* sInitializeSRWLock)
|
|
4378
4400
|
(PSRWLOCK SRWLock);
|
|
4379
4401
|
|
|
@@ -4397,17 +4419,19 @@ typedef VOID (WINAPI* sReleaseSRWLockExclusive)
|
|
|
4397
4419
|
|
|
4398
4420
|
|
|
4399
4421
|
|
|
4400
|
-
/*
|
|
4422
|
+
/* Ntdll function pointers */
|
|
4401
4423
|
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
|
|
4402
4424
|
extern sNtDeviceIoControlFile pNtDeviceIoControlFile;
|
|
4403
4425
|
extern sNtQueryInformationFile pNtQueryInformationFile;
|
|
4404
4426
|
extern sNtSetInformationFile pNtSetInformationFile;
|
|
4427
|
+
extern sNtQuerySystemInformation pNtQuerySystemInformation;
|
|
4405
4428
|
|
|
4406
4429
|
|
|
4407
4430
|
/* Kernel32 function pointers */
|
|
4408
4431
|
extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
|
|
4409
4432
|
extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
|
|
4410
4433
|
extern sCreateSymbolicLinkW pCreateSymbolicLinkW;
|
|
4434
|
+
extern sCancelIoEx pCancelIoEx;
|
|
4411
4435
|
extern sInitializeSRWLock pInitializeSRWLock;
|
|
4412
4436
|
extern sAcquireSRWLockShared pAcquireSRWLockShared;
|
|
4413
4437
|
extern sAcquireSRWLockExclusive pAcquireSRWLockExclusive;
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
#include <assert.h>
|
|
23
23
|
|
|
24
24
|
#include "uv.h"
|
|
25
|
-
#include "../uv-common.h"
|
|
26
25
|
#include "internal.h"
|
|
27
26
|
|
|
27
|
+
|
|
28
28
|
/* Whether ipv6 is supported */
|
|
29
29
|
int uv_allow_ipv6;
|
|
30
30
|
|
|
@@ -468,3 +468,90 @@ int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
|
|
|
468
468
|
return SOCKET_ERROR;
|
|
469
469
|
}
|
|
470
470
|
}
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
|
|
474
|
+
OVERLAPPED* overlapped) {
|
|
475
|
+
IO_STATUS_BLOCK iosb;
|
|
476
|
+
IO_STATUS_BLOCK* iosb_ptr;
|
|
477
|
+
HANDLE event = NULL;
|
|
478
|
+
void* apc_context;
|
|
479
|
+
NTSTATUS status;
|
|
480
|
+
DWORD error;
|
|
481
|
+
|
|
482
|
+
if (overlapped != NULL) {
|
|
483
|
+
/* Overlapped operation. */
|
|
484
|
+
iosb_ptr = (IO_STATUS_BLOCK*) &overlapped->Internal;
|
|
485
|
+
event = overlapped->hEvent;
|
|
486
|
+
|
|
487
|
+
/* Do not report iocp completion if hEvent is tagged. */
|
|
488
|
+
if ((uintptr_t) event & 1) {
|
|
489
|
+
event = (HANDLE)((uintptr_t) event & ~(uintptr_t) 1);
|
|
490
|
+
apc_context = NULL;
|
|
491
|
+
} else {
|
|
492
|
+
apc_context = overlapped;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
} else {
|
|
496
|
+
/* Blocking operation. */
|
|
497
|
+
iosb_ptr = &iosb;
|
|
498
|
+
event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
499
|
+
if (event == NULL) {
|
|
500
|
+
return SOCKET_ERROR;
|
|
501
|
+
}
|
|
502
|
+
apc_context = NULL;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
iosb_ptr->Status = STATUS_PENDING;
|
|
506
|
+
status = pNtDeviceIoControlFile((HANDLE) socket,
|
|
507
|
+
event,
|
|
508
|
+
NULL,
|
|
509
|
+
apc_context,
|
|
510
|
+
iosb_ptr,
|
|
511
|
+
IOCTL_AFD_POLL,
|
|
512
|
+
info,
|
|
513
|
+
sizeof *info,
|
|
514
|
+
info,
|
|
515
|
+
sizeof *info);
|
|
516
|
+
|
|
517
|
+
if (overlapped == NULL) {
|
|
518
|
+
/* If this is a blocking operation, wait for the event to become */
|
|
519
|
+
/* signaled, and then grab the real status from the io status block. */
|
|
520
|
+
if (status == STATUS_PENDING) {
|
|
521
|
+
DWORD r = WaitForSingleObject(event, INFINITE);
|
|
522
|
+
|
|
523
|
+
if (r == WAIT_FAILED) {
|
|
524
|
+
DWORD saved_error = GetLastError();
|
|
525
|
+
CloseHandle(event);
|
|
526
|
+
WSASetLastError(saved_error);
|
|
527
|
+
return SOCKET_ERROR;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
status = iosb.Status;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
CloseHandle(event);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
switch (status) {
|
|
537
|
+
case STATUS_SUCCESS:
|
|
538
|
+
error = ERROR_SUCCESS;
|
|
539
|
+
break;
|
|
540
|
+
|
|
541
|
+
case STATUS_PENDING:
|
|
542
|
+
error = WSA_IO_PENDING;
|
|
543
|
+
break;
|
|
544
|
+
|
|
545
|
+
default:
|
|
546
|
+
error = uv_ntstatus_to_winsock_error(status);
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
WSASetLastError(error);
|
|
551
|
+
|
|
552
|
+
if (error == ERROR_SUCCESS) {
|
|
553
|
+
return 0;
|
|
554
|
+
} else {
|
|
555
|
+
return SOCKET_ERROR;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
@@ -43,11 +43,15 @@
|
|
|
43
43
|
#endif
|
|
44
44
|
|
|
45
45
|
#ifndef IPV6_V6ONLY
|
|
46
|
-
|
|
46
|
+
# define IPV6_V6ONLY 27
|
|
47
47
|
#endif
|
|
48
48
|
|
|
49
49
|
#ifndef IPV6_HOPLIMIT
|
|
50
|
-
|
|
50
|
+
# define IPV6_HOPLIMIT 21
|
|
51
|
+
#endif
|
|
52
|
+
|
|
53
|
+
#ifndef SIO_BASE_HANDLE
|
|
54
|
+
# define SIO_BASE_HANDLE 0x48000022
|
|
51
55
|
#endif
|
|
52
56
|
|
|
53
57
|
/*
|
|
@@ -81,6 +85,32 @@
|
|
|
81
85
|
#define AFD_OVERLAPPED 0x00000002
|
|
82
86
|
#define AFD_IMMEDIATE 0x00000004
|
|
83
87
|
|
|
88
|
+
#define AFD_POLL_RECEIVE_BIT 0
|
|
89
|
+
#define AFD_POLL_RECEIVE (1 << AFD_POLL_RECEIVE_BIT)
|
|
90
|
+
#define AFD_POLL_RECEIVE_EXPEDITED_BIT 1
|
|
91
|
+
#define AFD_POLL_RECEIVE_EXPEDITED (1 << AFD_POLL_RECEIVE_EXPEDITED_BIT)
|
|
92
|
+
#define AFD_POLL_SEND_BIT 2
|
|
93
|
+
#define AFD_POLL_SEND (1 << AFD_POLL_SEND_BIT)
|
|
94
|
+
#define AFD_POLL_DISCONNECT_BIT 3
|
|
95
|
+
#define AFD_POLL_DISCONNECT (1 << AFD_POLL_DISCONNECT_BIT)
|
|
96
|
+
#define AFD_POLL_ABORT_BIT 4
|
|
97
|
+
#define AFD_POLL_ABORT (1 << AFD_POLL_ABORT_BIT)
|
|
98
|
+
#define AFD_POLL_LOCAL_CLOSE_BIT 5
|
|
99
|
+
#define AFD_POLL_LOCAL_CLOSE (1 << AFD_POLL_LOCAL_CLOSE_BIT)
|
|
100
|
+
#define AFD_POLL_CONNECT_BIT 6
|
|
101
|
+
#define AFD_POLL_CONNECT (1 << AFD_POLL_CONNECT_BIT)
|
|
102
|
+
#define AFD_POLL_ACCEPT_BIT 7
|
|
103
|
+
#define AFD_POLL_ACCEPT (1 << AFD_POLL_ACCEPT_BIT)
|
|
104
|
+
#define AFD_POLL_CONNECT_FAIL_BIT 8
|
|
105
|
+
#define AFD_POLL_CONNECT_FAIL (1 << AFD_POLL_CONNECT_FAIL_BIT)
|
|
106
|
+
#define AFD_POLL_QOS_BIT 9
|
|
107
|
+
#define AFD_POLL_QOS (1 << AFD_POLL_QOS_BIT)
|
|
108
|
+
#define AFD_POLL_GROUP_QOS_BIT 10
|
|
109
|
+
#define AFD_POLL_GROUP_QOS (1 << AFD_POLL_GROUP_QOS_BIT)
|
|
110
|
+
|
|
111
|
+
#define AFD_NUM_POLL_EVENTS 11
|
|
112
|
+
#define AFD_POLL_ALL ((1 << AFD_NUM_POLL_EVENTS) - 1)
|
|
113
|
+
|
|
84
114
|
typedef struct _AFD_RECV_DATAGRAM_INFO {
|
|
85
115
|
LPWSABUF BufferArray;
|
|
86
116
|
ULONG BufferCount;
|
|
@@ -105,6 +135,7 @@ typedef struct _AFD_RECV_INFO {
|
|
|
105
135
|
|
|
106
136
|
#define AFD_RECEIVE 5
|
|
107
137
|
#define AFD_RECEIVE_DATAGRAM 6
|
|
138
|
+
#define AFD_POLL 9
|
|
108
139
|
|
|
109
140
|
#define IOCTL_AFD_RECEIVE \
|
|
110
141
|
_AFD_CONTROL_CODE(AFD_RECEIVE, METHOD_NEITHER)
|
|
@@ -112,8 +143,10 @@ typedef struct _AFD_RECV_INFO {
|
|
|
112
143
|
#define IOCTL_AFD_RECEIVE_DATAGRAM \
|
|
113
144
|
_AFD_CONTROL_CODE(AFD_RECEIVE_DATAGRAM, METHOD_NEITHER)
|
|
114
145
|
|
|
115
|
-
#
|
|
146
|
+
#define IOCTL_AFD_POLL \
|
|
147
|
+
_AFD_CONTROL_CODE(AFD_POLL, METHOD_BUFFERED)
|
|
116
148
|
|
|
149
|
+
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
|
|
117
150
|
typedef struct _IP_ADAPTER_UNICAST_ADDRESS_XP {
|
|
118
151
|
/* FIXME: __C89_NAMELESS was removed */
|
|
119
152
|
/* __C89_NAMELESS */ union {
|
|
@@ -41,16 +41,16 @@ static int argument;
|
|
|
41
41
|
static int64_t start_time;
|
|
42
42
|
static int64_t end_time;
|
|
43
43
|
|
|
44
|
-
/* callback method. may issue another call */
|
|
45
|
-
static void aresbynamecallback( void *arg,
|
|
46
|
-
int status,
|
|
47
|
-
int timeouts,
|
|
48
|
-
struct hostent *hostent) {
|
|
49
|
-
ares_callbacks++;
|
|
50
|
-
if (status != 0) {
|
|
51
|
-
ares_errors++;
|
|
52
|
-
}
|
|
53
44
|
|
|
45
|
+
/* callback method. */
|
|
46
|
+
static void aresbynamecallback(void *arg,
|
|
47
|
+
int status,
|
|
48
|
+
int timeouts,
|
|
49
|
+
struct hostent *hostent) {
|
|
50
|
+
ares_callbacks++;
|
|
51
|
+
if (status != 0) {
|
|
52
|
+
ares_errors++;
|
|
53
|
+
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
|
|
@@ -89,30 +89,29 @@ BENCHMARK_IMPL(gethostbyname) {
|
|
|
89
89
|
ares_callbacks = 0;
|
|
90
90
|
ares_errors = 0;
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
start_time = uv_now(loop);
|
|
92
|
+
start_time = uv_hrtime();
|
|
94
93
|
|
|
95
94
|
prep_tcploopback();
|
|
96
95
|
|
|
97
96
|
for (ares_start = 0; ares_start < NUM_CALLS_TO_START; ares_start++) {
|
|
98
97
|
ares_gethostbyname(channel,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
98
|
+
"echos.srv",
|
|
99
|
+
AF_INET,
|
|
100
|
+
&aresbynamecallback,
|
|
101
|
+
&argument);
|
|
103
102
|
}
|
|
104
103
|
|
|
105
104
|
uv_run(loop);
|
|
106
105
|
|
|
107
106
|
uv_ares_destroy(loop, channel);
|
|
108
107
|
|
|
109
|
-
end_time =
|
|
108
|
+
end_time = uv_hrtime();
|
|
110
109
|
|
|
111
110
|
if (ares_errors > 0) {
|
|
112
111
|
printf("There were %d failures\n", ares_errors);
|
|
113
112
|
}
|
|
114
113
|
LOGF("ares_gethostbyname: %.0f req/s\n",
|
|
115
|
-
|
|
114
|
+
1e9 * ares_callbacks / (double)(end_time - start_time));
|
|
116
115
|
|
|
117
116
|
return 0;
|
|
118
117
|
}
|
|
@@ -0,0 +1,164 @@
|
|
|
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
|
+
#include "task.h"
|
|
23
|
+
#include "uv.h"
|
|
24
|
+
|
|
25
|
+
#include <stdio.h>
|
|
26
|
+
#include <stdlib.h>
|
|
27
|
+
|
|
28
|
+
#define NUM_SYNC_REQS (10 * 1e5)
|
|
29
|
+
#define NUM_ASYNC_REQS (1 * 1e5)
|
|
30
|
+
#define MAX_CONCURRENT_REQS 32
|
|
31
|
+
|
|
32
|
+
#define sync_stat(req, path) \
|
|
33
|
+
do { \
|
|
34
|
+
uv_fs_stat(uv_default_loop(), (req), (path), NULL); \
|
|
35
|
+
uv_fs_req_cleanup((req)); \
|
|
36
|
+
} \
|
|
37
|
+
while (0)
|
|
38
|
+
|
|
39
|
+
struct async_req {
|
|
40
|
+
const char* path;
|
|
41
|
+
uv_fs_t fs_req;
|
|
42
|
+
int* count;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
static const char* fmt(double d) {
|
|
47
|
+
uint64_t v;
|
|
48
|
+
char* p;
|
|
49
|
+
|
|
50
|
+
p = (char *) calloc(1, 32) + 31; /* leaks memory */
|
|
51
|
+
v = d;
|
|
52
|
+
|
|
53
|
+
#if 0 /* works but we don't care about fractional precision */
|
|
54
|
+
if (d - v >= 0.01) {
|
|
55
|
+
*--p = '0' + (uint64_t) (d * 100) % 10;
|
|
56
|
+
*--p = '0' + (uint64_t) (d * 10) % 10;
|
|
57
|
+
*--p = '.';
|
|
58
|
+
}
|
|
59
|
+
#endif
|
|
60
|
+
|
|
61
|
+
if (v == 0)
|
|
62
|
+
*--p = '0';
|
|
63
|
+
|
|
64
|
+
while (v) {
|
|
65
|
+
if (v) *--p = '0' + (v % 10), v /= 10;
|
|
66
|
+
if (v) *--p = '0' + (v % 10), v /= 10;
|
|
67
|
+
if (v) *--p = '0' + (v % 10), v /= 10;
|
|
68
|
+
if (v) *--p = ',';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return p;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
static void warmup(const char* path) {
|
|
76
|
+
uv_fs_t reqs[MAX_CONCURRENT_REQS];
|
|
77
|
+
int i;
|
|
78
|
+
|
|
79
|
+
/* warm up the thread pool */
|
|
80
|
+
for (i = 0; i < ARRAY_SIZE(reqs); i++)
|
|
81
|
+
uv_fs_stat(uv_default_loop(), reqs + i, path, uv_fs_req_cleanup);
|
|
82
|
+
|
|
83
|
+
uv_run(uv_default_loop());
|
|
84
|
+
|
|
85
|
+
/* warm up the OS dirent cache */
|
|
86
|
+
for (i = 0; i < 16; i++)
|
|
87
|
+
sync_stat(reqs + 0, path);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
static void sync_bench(const char* path) {
|
|
92
|
+
uint64_t before;
|
|
93
|
+
uint64_t after;
|
|
94
|
+
uv_fs_t req;
|
|
95
|
+
int i;
|
|
96
|
+
|
|
97
|
+
/* do the sync benchmark */
|
|
98
|
+
before = uv_hrtime();
|
|
99
|
+
|
|
100
|
+
for (i = 0; i < NUM_SYNC_REQS; i++)
|
|
101
|
+
sync_stat(&req, path);
|
|
102
|
+
|
|
103
|
+
after = uv_hrtime();
|
|
104
|
+
|
|
105
|
+
printf("%s stats (sync): %.2fs (%s/s)\n",
|
|
106
|
+
fmt(1.0 * NUM_SYNC_REQS),
|
|
107
|
+
(after - before) / 1e9,
|
|
108
|
+
fmt((1.0 * NUM_SYNC_REQS) / ((after - before) / 1e9)));
|
|
109
|
+
fflush(stdout);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
static void stat_cb(uv_fs_t* fs_req) {
|
|
114
|
+
struct async_req* req = container_of(fs_req, struct async_req, fs_req);
|
|
115
|
+
uv_fs_req_cleanup(&req->fs_req);
|
|
116
|
+
if (*req->count == 0) return;
|
|
117
|
+
uv_fs_stat(uv_default_loop(), &req->fs_req, req->path, stat_cb);
|
|
118
|
+
(*req->count)--;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
static void async_bench(const char* path) {
|
|
123
|
+
struct async_req reqs[MAX_CONCURRENT_REQS];
|
|
124
|
+
struct async_req* req;
|
|
125
|
+
uint64_t before;
|
|
126
|
+
uint64_t after;
|
|
127
|
+
int count;
|
|
128
|
+
int i;
|
|
129
|
+
|
|
130
|
+
for (i = 1; i <= MAX_CONCURRENT_REQS; i++) {
|
|
131
|
+
count = NUM_ASYNC_REQS;
|
|
132
|
+
|
|
133
|
+
for (req = reqs; req < reqs + i; req++) {
|
|
134
|
+
req->path = path;
|
|
135
|
+
req->count = &count;
|
|
136
|
+
uv_fs_stat(uv_default_loop(), &req->fs_req, req->path, stat_cb);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
before = uv_hrtime();
|
|
140
|
+
uv_run(uv_default_loop());
|
|
141
|
+
after = uv_hrtime();
|
|
142
|
+
|
|
143
|
+
printf("%s stats (%d concurrent): %.2fs (%s/s)\n",
|
|
144
|
+
fmt(1.0 * NUM_ASYNC_REQS),
|
|
145
|
+
i,
|
|
146
|
+
(after - before) / 1e9,
|
|
147
|
+
fmt((1.0 * NUM_ASYNC_REQS) / ((after - before) / 1e9)));
|
|
148
|
+
fflush(stdout);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
/* This benchmark aims to measure the overhead of doing I/O syscalls from
|
|
154
|
+
* the thread pool. The stat() syscall was chosen because its results are
|
|
155
|
+
* easy for the operating system to cache, taking the actual I/O overhead
|
|
156
|
+
* out of the equation.
|
|
157
|
+
*/
|
|
158
|
+
BENCHMARK_IMPL(fs_stat) {
|
|
159
|
+
const char path[] = ".";
|
|
160
|
+
warmup(path);
|
|
161
|
+
sync_bench(path);
|
|
162
|
+
async_bench(path);
|
|
163
|
+
return 0;
|
|
164
|
+
}
|