From 0854ccff976f2893a7f04aaa4b48090f423802a5 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 8 Oct 2009 15:18:56 -0400 Subject: [PATCH] Support for sys_futex autodetection Signed-off-by: Mathieu Desnoyers --- Makefile.am | 8 ++++++-- configure.ac | 27 ++++++++++++++++++++++++++- tests/Makefile.am | 6 +++++- urcu-defer.c | 9 +++------ urcu-qsbr-static.h | 7 ++----- urcu-qsbr.c | 2 +- urcu-static.h | 7 ++----- urcu.c | 2 +- 8 files changed, 46 insertions(+), 22 deletions(-) diff --git a/Makefile.am b/Makefile.am index f7d64f6..28e414c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,8 +6,9 @@ AM_LDFLAGS=-lpthread SUBDIRS = tests include_HEADERS = urcu.h $(top_srcdir)/urcu-*.h -nobase_dist_include_HEADERS = urcu/compiler.h urcu/hlist.h urcu/list.h urcu/rculist.h urcu/system.h -nobase_nodist_include_HEADERS = urcu/arch.h urcu/uatomic_arch.h +nobase_dist_include_HEADERS = urcu/compiler.h urcu/hlist.h urcu/list.h \ + urcu/rculist.h urcu/system.h urcu/urcu-futex.h +nobase_nodist_include_HEADERS = urcu/arch.h urcu/uatomic_arch.h urcu/config.h EXTRA_DIST = $(top_srcdir)/urcu/arch_*.h $(top_srcdir)/urcu/uatomic_arch_*.h \ gpl-2.0.txt lgpl-2.1.txt lgpl-relicensing.txt \ @@ -19,6 +20,9 @@ else COMPAT= endif +if COMPAT_FUTEX +COMPAT+=compat_futex.c +endif lib_LTLIBRARIES = liburcu.la liburcu-mb.la liburcu-defer.la liburcu-qsbr.la liburcu-bp.la diff --git a/configure.ac b/configure.ac index 40603c4..2c1b6c0 100644 --- a/configure.ac +++ b/configure.ac @@ -12,6 +12,7 @@ AC_CONFIG_SRCDIR([urcu.h]) AH_TEMPLATE([CONFIG_SMP], [Enable SMP support. With SMP support enabled, uniprocessors are also supported. With SMP support disabled, UP systems work fine, but the behavior of SMP systems is undefined.]) AH_TEMPLATE([CONFIG_HAVE_FENCE], [Defined when on a system that has memory fence instructions.]) +AH_TEMPLATE([CONFIG_HAVE_FUTEX], [Defined when on a system with futex support.]) AC_CONFIG_HEADERS([config.h]) # Checks for programs. @@ -59,9 +60,33 @@ if test "x$ARCHTYPE" = "xx86" -a "x$target_cpu" != "xi386" -a "x$target_cpu" != fi ] +AC_MSG_CHECKING([presence of sys_futex()]) +AC_TRY_COMPILE( +[ +#include +], +[ +#ifndef __NR_futex +#error "futexes not available" +#endif +], +[ + AC_MSG_RESULT([yes]) + AC_DEFINE([CONFIG_HAVE_FUTEX], [1]) + compat_futex_test=0 +] +, +[ + AC_MSG_RESULT([no]) + compat_futex_test=1 +] +) + +AM_CONDITIONAL([COMPAT_FUTEX], [ test "x$compat_futex_test" = "x1" ]) + AM_CONDITIONAL([GCC_API], [test "x$ARCHTYPE" != xx86 -a "x$ARCHTYPE" != xppc]) -AM_CONDITIONAL([COMPAT_ARCH], [test "x$SUBARCHTYPE" == xx86compat ]) +AM_CONDITIONAL([COMPAT_ARCH], [test "x$SUBARCHTYPE" = xx86compat ]) AC_ARG_ENABLE([smp-support], [ --disable-smp-support Disable SMP support. Warning: only use this on uniprocessor systems. [[default=enabled]]], [def_smp_support=$enableval], [def_smp_support="yes"]) diff --git a/tests/Makefile.am b/tests/Makefile.am index 983ee67..fdc82b1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -14,11 +14,15 @@ noinst_PROGRAMS = test_urcu test_urcu_dynamic_link test_urcu_timing \ noinst_HEADERS = rcutorture.h if COMPAT_ARCH -COMPAT=$(top_builddir)/compat_arch_@ARCHTYPE@.c +COMPAT=$(top_srcdir)/compat_arch_@ARCHTYPE@.c else COMPAT= endif +if COMPAT_FUTEX +COMPAT+=$(top_srcdir)/compat_futex.c +endif + URCU_SIGNAL=$(top_builddir)/urcu.c $(top_builddir)/urcu-pointer.c $(COMPAT) # URCU_SIGNAL_YIELD uses urcu.c but -DDEBUG_YIELD must be defined URCU_SIGNAL_YIELD=$(top_builddir)/urcu.c $(top_builddir)/urcu-pointer.c $(COMPAT) diff --git a/urcu-defer.c b/urcu-defer.c index a38b5c0..ed627a3 100644 --- a/urcu-defer.c +++ b/urcu-defer.c @@ -32,14 +32,11 @@ #include #include +#include "urcu/urcu-futex.h" #include "urcu-defer-static.h" /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ #include "urcu-defer.h" -#define futex(...) syscall(__NR_futex, __VA_ARGS__) -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 - void __attribute__((destructor)) urcu_defer_exit(void); extern void synchronize_rcu(void); @@ -101,7 +98,7 @@ static void wake_up_defer(void) { if (unlikely(uatomic_read(&defer_thread_futex) == -1)) { uatomic_set(&defer_thread_futex, 0); - futex(&defer_thread_futex, FUTEX_WAKE, 1, + futex_noasync(&defer_thread_futex, FUTEX_WAKE, 1, NULL, NULL, 0); } } @@ -134,7 +131,7 @@ static void wait_defer(void) } else { smp_rmb(); /* Read queue before read futex */ if (uatomic_read(&defer_thread_futex) == -1) - futex(&defer_thread_futex, FUTEX_WAIT, -1, + futex_noasync(&defer_thread_futex, FUTEX_WAIT, -1, NULL, NULL, 0); } } diff --git a/urcu-qsbr-static.h b/urcu-qsbr-static.h index 150bc09..e49a041 100644 --- a/urcu-qsbr-static.h +++ b/urcu-qsbr-static.h @@ -41,10 +41,7 @@ #include #include #include - -#define futex(...) syscall(__NR_futex, __VA_ARGS__) -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 +#include /* * This code section can only be included in LGPL 2.1 compatible source code. @@ -154,7 +151,7 @@ static inline void wake_up_gp(void) { if (unlikely(uatomic_read(&gp_futex) == -1)) { uatomic_set(&gp_futex, 0); - futex(&gp_futex, FUTEX_WAKE, 1, + futex_noasync(&gp_futex, FUTEX_WAKE, 1, NULL, NULL, 0); } } diff --git a/urcu-qsbr.c b/urcu-qsbr.c index 56d86f9..5c6d49b 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -102,7 +102,7 @@ static void wait_gp(void) /* Read reader_gp before read futex */ smp_rmb(); if (uatomic_read(&gp_futex) == -1) - futex(&gp_futex, FUTEX_WAIT, -1, + futex_noasync(&gp_futex, FUTEX_WAIT, -1, NULL, NULL, 0); } diff --git a/urcu-static.h b/urcu-static.h index 2e7371e..97d94dc 100644 --- a/urcu-static.h +++ b/urcu-static.h @@ -39,10 +39,7 @@ #include #include #include - -#define futex(...) syscall(__NR_futex, __VA_ARGS__) -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 +#include /* * This code section can only be included in LGPL 2.1 compatible source code. @@ -182,7 +179,7 @@ static inline void wake_up_gp(void) { if (unlikely(uatomic_read(&gp_futex) == -1)) { uatomic_set(&gp_futex, 0); - futex(&gp_futex, FUTEX_WAKE, 1, + futex_async(&gp_futex, FUTEX_WAKE, 1, NULL, NULL, 0); } } diff --git a/urcu.c b/urcu.c index 8ff39db..0ebe4fd 100644 --- a/urcu.c +++ b/urcu.c @@ -208,7 +208,7 @@ static void wait_gp(void) /* Read reader_gp before read futex */ force_mb_all_threads(); if (uatomic_read(&gp_futex) == -1) - futex(&gp_futex, FUTEX_WAIT, -1, + futex_async(&gp_futex, FUTEX_WAIT, -1, NULL, NULL, 0); } -- 2.34.1