diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2015-02-24 21:03:00 +0100 |
---|---|---|
committer | Rod Vagg <rod@vagg.org> | 2015-02-25 11:52:11 -0600 |
commit | 739fda16a93cadcefb59190669cfb7765d2fb8fa (patch) | |
tree | 1d5f67f417248902910f604cc6f227ac1e76ed7a /deps/uv/src/unix/async.c | |
parent | 06ee782f2462f2658ecda600044cf1e2abfdea53 (diff) | |
download | android-node-v8-739fda16a93cadcefb59190669cfb7765d2fb8fa.tar.gz android-node-v8-739fda16a93cadcefb59190669cfb7765d2fb8fa.tar.bz2 android-node-v8-739fda16a93cadcefb59190669cfb7765d2fb8fa.zip |
deps: update libuv to 1.4.1
PR-URL: https://github.com/iojs/io.js/pull/940
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Rod Vagg <rod@vagg.org>
Diffstat (limited to 'deps/uv/src/unix/async.c')
-rw-r--r-- | deps/uv/src/unix/async.c | 42 |
1 files changed, 7 insertions, 35 deletions
diff --git a/deps/uv/src/unix/async.c b/deps/uv/src/unix/async.c index b794ea6121..9ff24aeb3d 100644 --- a/deps/uv/src/unix/async.c +++ b/deps/uv/src/unix/async.c @@ -24,6 +24,7 @@ #include "uv.h" #include "internal.h" +#include "atomic-ops.h" #include <errno.h> #include <stdio.h> /* snprintf() */ @@ -35,7 +36,6 @@ static void uv__async_event(uv_loop_t* loop, struct uv__async* w, unsigned int nevents); -static int uv__async_make_pending(int* pending); static int uv__async_eventfd(void); @@ -58,7 +58,11 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { int uv_async_send(uv_async_t* handle) { - if (uv__async_make_pending(&handle->pending) == 0) + /* Do a cheap read first. */ + if (ACCESS_ONCE(int, handle->pending) != 0) + return 0; + + if (cmpxchgi(&handle->pending, 0, 1) == 0) uv__async_send(&handle->loop->async_watcher); return 0; @@ -80,9 +84,8 @@ static void uv__async_event(uv_loop_t* loop, QUEUE_FOREACH(q, &loop->async_handles) { h = QUEUE_DATA(q, uv_async_t, queue); - if (h->pending == 0) + if (cmpxchgi(&h->pending, 1, 0) == 0) continue; - h->pending = 0; if (h->async_cb == NULL) continue; @@ -91,37 +94,6 @@ static void uv__async_event(uv_loop_t* loop, } -static int uv__async_make_pending(int* pending) { - /* Do a cheap read first. */ - if (ACCESS_ONCE(int, *pending) != 0) - return 1; - - /* Micro-optimization: use atomic memory operations to detect if we've been - * preempted by another thread and don't have to make an expensive syscall. - * This speeds up the heavily contended case by about 1-2% and has little - * if any impact on the non-contended case. - * - * Use XCHG instead of the CMPXCHG that __sync_val_compare_and_swap() emits - * on x86, it's about 4x faster. It probably makes zero difference in the - * grand scheme of things but I'm OCD enough not to let this one pass. - */ -#if defined(__i386__) || defined(__x86_64__) - { - unsigned int val = 1; - __asm__ __volatile__ ("xchgl %0, %1" - : "+r" (val) - : "m" (*pending)); - return val != 0; - } -#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0) - return __sync_val_compare_and_swap(pending, 0, 1) != 0; -#else - ACCESS_ONCE(int, *pending) = 1; - return 0; -#endif -} - - static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { struct uv__async* wa; char buf[1024]; |