diff options
author | Eric Wong <normalperson@yhbt.net> | 2010-09-18 06:43:19 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2010-09-18 06:59:53 +0000 |
commit | c658a2be7355ceee72736cc17754022dc7abfa9f (patch) | |
tree | 7c0e91b92270eca19ba1344f1e666e2c4c98cb96 | |
parent | 7a0bb1afb81da3c83f2cc59403826e1f855d3f0d (diff) | |
download | raindrops-c658a2be7355ceee72736cc17754022dc7abfa9f.tar.gz |
This allows non-GCC 4.x users to experience Raindrops.
-rw-r--r-- | TODO | 1 | ||||
-rw-r--r-- | ext/raindrops/extconf.rb | 26 | ||||
-rw-r--r-- | ext/raindrops/linux_inet_diag.c | 2 | ||||
-rw-r--r-- | ext/raindrops/raindrops.c | 1 | ||||
-rw-r--r-- | ext/raindrops/raindrops_atomic.h | 23 |
5 files changed, 51 insertions, 2 deletions
@@ -1,2 +1 @@ -* more portable atomics for non-GCC systems (libatomicops?) * pure Ruby version for non-forking servers diff --git a/ext/raindrops/extconf.rb b/ext/raindrops/extconf.rb index d637287..09d6e36 100644 --- a/ext/raindrops/extconf.rb +++ b/ext/raindrops/extconf.rb @@ -7,5 +7,31 @@ have_func('munmap', 'sys/mman.h') or abort 'munmap() not found' have_func("rb_struct_alloc_noinit") have_func('rb_thread_blocking_region') +checking_for "GCC 4+ atomic builtins" do + src = <<SRC +int main(int argc, char * const argv[]) { + volatile unsigned long i = 0; + __sync_add_and_fetch(&i, argc); + __sync_sub_and_fetch(&i, argc); + return 0; +} +SRC + + if try_run(src) + $defs.push(format("-DHAVE_GCC_ATOMIC_BUILTINS")) + true + else + false + end +end or have_header('atomic_ops.h') or abort <<-SRC + +libatomic_ops is required if GCC 4+ is not used. +See http://www.hpl.hp.com/research/linux/atomic_ops/ + +Users of Debian-based distros may run: + + apt-get install libatomic-ops-dev +SRC + dir_config('raindrops') create_makefile('raindrops_ext') diff --git a/ext/raindrops/linux_inet_diag.c b/ext/raindrops/linux_inet_diag.c index 954a73c..2c2978b 100644 --- a/ext/raindrops/linux_inet_diag.c +++ b/ext/raindrops/linux_inet_diag.c @@ -144,7 +144,7 @@ static VALUE diag(void *ptr) } req; struct msghdr msg; const char *err = NULL; - unsigned seq = __sync_add_and_fetch(&g_seq, 1); + unsigned seq = ++g_seq; /* not atomic, rely on GVL for now */ int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG); if (fd < 0) diff --git a/ext/raindrops/raindrops.c b/ext/raindrops/raindrops.c index eb4694e..4b6a773 100644 --- a/ext/raindrops/raindrops.c +++ b/ext/raindrops/raindrops.c @@ -3,6 +3,7 @@ #include <assert.h> #include <errno.h> #include <stddef.h> +#include "raindrops_atomic.h" /* * most modern CPUs have a cache-line size of 64 or 128. diff --git a/ext/raindrops/raindrops_atomic.h b/ext/raindrops/raindrops_atomic.h new file mode 100644 index 0000000..fd5f23b --- /dev/null +++ b/ext/raindrops/raindrops_atomic.h @@ -0,0 +1,23 @@ +/* + * use wrappers around libatomic-ops for folks that don't have GCC + * or a new enough version of GCC + */ +#ifndef HAVE_GCC_ATOMIC_BUILTINS +#include <atomic_ops.h> + +static inline unsigned long +__sync_add_and_fetch(unsigned long *dst, unsigned long incr) +{ + AO_t tmp = AO_fetch_and_add((AO_t *)dst, (AO_t)incr); + + return (unsigned long)tmp + incr; +} + +static inline unsigned long +__sync_sub_and_fetch(unsigned long *dst, unsigned long incr) +{ + AO_t tmp = AO_fetch_and_add((AO_t *)dst, (AO_t)(-(long)incr)); + + return (unsigned long)tmp - incr; +} +#endif /* HAVE_GCC_ATOMIC_BUILTINS */ |