From 3d9c1ebfeb3fe37a368fd8ab7e94ebcf411878ab Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 2 Jul 2012 04:27:22 +0200 Subject: [PATCH] unix: speed up uv_async_send() some more Use atomic compare-and-swap to detect if we've been preempted by another thread and therefore can avoid making the expensive write() syscall. Speeds up the heavily contended case by about 1-2% and has little if any impact on the non-contended case. I wasn't able to measure the difference at any rate. --- src/unix/async.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/unix/async.c b/src/unix/async.c index b4e0428e1..aacffe94f 100644 --- a/src/unix/async.c +++ b/src/unix/async.c @@ -53,7 +53,17 @@ int uv_async_send(uv_async_t* handle) { if (handle->pending) return 0; - handle->pending = 1; /* XXX needs a memory barrier? */ + /* Micro-optimization: use atomic compare-and-swap 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. + */ +#if __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 1 /* gcc >= 4.1 */ + if (__sync_val_compare_and_swap(&handle->pending, 0, 1)) + return 0; +#else + handle->pending = 1; +#endif do r = write(handle->loop->async_pipefd[1], "x", 1);