+2011-11-03 Userspace RCU 0.6.6
+ * qsbr vs call_rcu : remove exit assertion
+ * Rename likely/unlikely to caa_likely/caa_unlikely
+ * Reinsert missing test_urcu_*.c files (missing in rename)
+ * rename test_qsbr to test_urcu_qsbr
+ * urcu-pointer: fix rcu_set_pointer unset return value
+ * Enhance API.txt documentation, add to Makefile as EXTRA_DIST
+
2011-09-29 Userspace RCU 0.6.5
* call_rcu: Document call_rcu requirements
* call_rcu: fix error handling of malloc error
README LICENSE compat_arch_x86.c \
urcu-call-rcu-impl.h urcu-defer-impl.h \
rculfhash-internal.h \
- ChangeLog API.txt
+ ChangeLog API.txt \
+ $(top_srcdir)/tests/*.sh
if COMPAT_ARCH
COMPAT=compat_arch_@ARCHTYPE@.c
- Alpha, ia64 and ARM architectures depend on 4.x gcc with atomic builtins
support.
+For developers using the git tree:
+
+This source tree is based on the autotools suite from GNU to simplify
+portability. Here are some things you should have on your system in order to
+compile the git repository tree :
+
+- GNU autotools (automake >=1.10, autoconf >=2.50, autoheader >=2.50)
+ (make sure your system wide "automake" points to a recent version!)
+- GNU Libtool >=2.2
+ (for more information, go to http://www.gnu.org/software/autoconf/)
+
+If you get the tree from the repository, you will need to use the "bootstrap"
+script in the root of the tree. It calls all the GNU tools needed to prepare the
+tree configuration.
+
QUICK START GUIDE
-----------------
# Process this file with autoconf to produce a configure script.
-AC_INIT([userspace-rcu], [0.6.5], [mathieu dot desnoyers at efficios dot com])
+AC_INIT([userspace-rcu],[0.6.6],[mathieu dot desnoyers at efficios dot com])
# Following the numbering scheme proposed by libtool for the library version
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
# Checks for programs.
AC_PROG_CC
AC_PROG_MAKE_SET
-AC_PROG_LIBTOOL
+LT_INIT
# Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE
i486) ARCHTYPE="x86";;
i586) ARCHTYPE="x86";;
i686) ARCHTYPE="x86";;
+ amd64) ARCHTYPE="x86";;
x86_64) ARCHTYPE="x86";;
powerpc) ARCHTYPE="ppc" ;;
ppc64) ARCHTYPE="ppc" ;;
if test "x$ARCHTYPE" = "xarm" ; then
AC_MSG_CHECKING([checking for dmb instruction])
-AC_TRY_COMPILE(
-[
-],
-[
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+]], [[
asm volatile("dmb":::"memory");
-],
-[
+]])],[
AC_MSG_RESULT([yes])
AC_DEFINE([CONFIG_RCU_ARM_HAVE_DMB], [1])
-]
-,
-[
+
+],[
AC_MSG_RESULT([no])
-]
-)
+
+])
fi
UATOMICSRC=urcu/uatomic/$ARCHTYPE.h
]
AC_MSG_CHECKING([sys_futex()])
-AC_TRY_COMPILE(
-[
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/syscall.h>
-],
-[
+]], [[
#ifndef __NR_futex
#error "futexes not available"
#endif
-],
-[
+]])],[
AC_MSG_RESULT([yes])
AC_DEFINE([CONFIG_RCU_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" ])
assert(!ret);
}
+void *rcu_dereference_sym_bp(void *p)
+{
+ return _rcu_dereference(p);
+}
+
+void *rcu_set_pointer_sym_bp(void **p, void *v)
+{
+ cmm_wmb();
+ return uatomic_set(p, v);
+}
+
+void *rcu_xchg_pointer_sym_bp(void **p, void *v)
+{
+ cmm_wmb();
+ return uatomic_xchg(p, v);
+}
+
+void *rcu_cmpxchg_pointer_sym_bp(void **p, void *old, void *_new)
+{
+ cmm_wmb();
+ return uatomic_cmpxchg(p, old, _new);
+}
+
DEFINE_RCU_FLAVOR()
#include "urcu-call-rcu-impl.h"
#include <stdlib.h>
#include <pthread.h>
-/*
- * See urcu-pointer.h and urcu/static/urcu-pointer.h for pointer
- * publication headers.
- */
-#include <urcu-pointer.h>
-
#ifdef __cplusplus
extern "C" {
#endif
* rcu_unregister_thread() should be called before the thread exits.
*/
+/*
+ * See urcu-pointer.h and urcu/static/urcu-pointer.h for pointer
+ * publication headers.
+ */
+#include <urcu-pointer.h>
+
#ifdef _LGPL_SOURCE
#include <urcu/static/urcu-bp.h>
#define rcu_read_lock_bp _rcu_read_lock
#define rcu_read_unlock_bp _rcu_read_unlock
+#define rcu_dereference_bp rcu_dereference
+#define rcu_cmpxchg_pointer_bp rcu_cmpxchg_pointer
+#define rcu_xchg_pointer_bp rcu_xchg_pointer
+#define rcu_set_pointer_bp rcu_set_pointer
+
#else /* !_LGPL_SOURCE */
/*
* See LGPL-only urcu/static/urcu-pointer.h for documentation.
*/
-extern void rcu_read_lock(void);
-extern void rcu_read_unlock(void);
+extern void rcu_read_lock(void)
+ __attribute__((weak));
+extern void rcu_read_unlock(void)
+ __attribute__((weak));
+
+extern void *rcu_dereference_sym_bp(void *p)
+ __attribute__((weak));
+#define rcu_dereference_bp(p) \
+ ({ \
+ typeof(p) _________p1 = URCU_FORCE_CAST(typeof(p), \
+ rcu_dereference_sym_bp(URCU_FORCE_CAST(void *, p))); \
+ (_________p1); \
+ })
+
+extern void *rcu_cmpxchg_pointer_sym_bp(void **p, void *old, void *_new)
+ __attribute__((weak));
+#define rcu_cmpxchg_pointer_bp(p, old, _new) \
+ ({ \
+ typeof(*(p)) _________pold = (old); \
+ typeof(*(p)) _________pnew = (_new); \
+ typeof(*(p)) _________p1 = URCU_FORCE_CAST(typeof(*(p)), \
+ rcu_cmpxchg_pointer_sym_bp(URCU_FORCE_CAST(void **, p),\
+ _________pold, \
+ _________pnew)); \
+ (_________p1); \
+ })
+
+extern void *rcu_xchg_pointer_sym_bp(void **p, void *v)
+ __attribute__((weak));
+#define rcu_xchg_pointer_bp(p, v) \
+ ({ \
+ typeof(*(p)) _________pv = (v); \
+ typeof(*(p)) _________p1 = URCU_FORCE_CAST(typeof(*(p)), \
+ rcu_xchg_pointer_sym_bp(URCU_FORCE_CAST(void **, p), \
+ _________pv)); \
+ (_________p1); \
+ })
+
+extern void *rcu_set_pointer_sym_bp(void **p, void *v)
+ __attribute__((weak));
+#define rcu_set_pointer_bp(p, v) \
+ ({ \
+ typeof(*(p)) _________pv = (v); \
+ typeof(*(p)) _________p1 = URCU_FORCE_CAST(typeof(*(p)), \
+ rcu_set_pointer_sym_bp(URCU_FORCE_CAST(void **, p), \
+ _________pv)); \
+ (_________p1); \
+ })
#endif /* !_LGPL_SOURCE */
int create_all_cpu_call_rcu_data(unsigned long flags);
void free_all_cpu_call_rcu_data(void);
+void call_rcu_before_fork(void);
+void call_rcu_after_fork_parent(void);
void call_rcu_after_fork_child(void);
#ifdef __cplusplus