From 5e77fc1f94c3572fca067d37667d74f8165e2434 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 3 Jun 2011 12:43:17 -0400 Subject: [PATCH] Map symbols to allow multiple RCU flavors to be used in one binary Probably need similar mapping for rcu_defer(). Definitely need backwards-compatibility mapping for programs compiled against old versions of the library. Signed-off-by: Paul E. McKenney Signed-off-by: Mathieu Desnoyers --- Makefile.am | 3 +- tests/Makefile.am | 33 ++++--- tests/rcutorture.h | 1 - tests/urcutorture.c | 13 +-- urcu-bp-map.h | 61 ++++++++++++ urcu-bp.c | 4 + urcu-bp.h | 8 +- urcu-call-rcu.c => urcu-call-rcu-impl.h | 2 - urcu-map.h | 117 ++++++++++++++++++++++++ urcu-qsbr-map.h | 63 +++++++++++++ urcu-qsbr.c | 36 +++++--- urcu-qsbr.h | 18 ++-- urcu.c | 5 + urcu.h | 20 +++- 14 files changed, 327 insertions(+), 57 deletions(-) create mode 100644 urcu-bp-map.h rename urcu-call-rcu.c => urcu-call-rcu-impl.h (99%) create mode 100644 urcu-map.h create mode 100644 urcu-qsbr-map.h diff --git a/Makefile.am b/Makefile.am index 776fa2b..4b70644 100644 --- a/Makefile.am +++ b/Makefile.am @@ -30,7 +30,7 @@ COMPAT+=compat_futex.c endif lib_LTLIBRARIES = liburcu.la liburcu-qsbr.la liburcu-mb.la liburcu-signal.la \ - liburcu-bp.la liburcu-defer.la liburcu-call.la \ + liburcu-bp.la liburcu-defer.la \ libwfqueue.la libwfstack.la librculfqueue.la librculfstack.la liburcu_la_SOURCES = urcu.c urcu-pointer.c $(COMPAT) @@ -45,7 +45,6 @@ liburcu_signal_la_CFLAGS = -DRCU_SIGNAL liburcu_bp_la_SOURCES = urcu-bp.c urcu-pointer.c $(COMPAT) -liburcu_call_la_SOURCES = urcu-call-rcu.c $(COMPAT) liburcu_defer_la_SOURCES = urcu-defer.c $(COMPAT) libwfqueue_la_SOURCES = wfqueue.c $(COMPAT) diff --git a/tests/Makefile.am b/tests/Makefile.am index 3c025a4..8dacb11 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -28,21 +28,20 @@ if COMPAT_FUTEX COMPAT+=$(top_srcdir)/compat_futex.c endif -URCU=$(top_srcdir)/urcu.c $(top_srcdir)/urcu-pointer.c $(top_srcdir)/urcu-call-rcu.c $(top_srcdir)/wfqueue.c $(COMPAT) -URCU_QSBR=$(top_srcdir)/urcu-qsbr.c $(top_srcdir)/urcu-pointer.c $(top_srcdir)/urcu-call-rcu.c $(top_srcdir)/wfqueue.c $(COMPAT) +URCU=$(top_srcdir)/urcu.c $(top_srcdir)/urcu-pointer.c $(top_srcdir)/wfqueue.c $(COMPAT) +URCU_QSBR=$(top_srcdir)/urcu-qsbr.c $(top_srcdir)/urcu-pointer.c $(top_srcdir)/wfqueue.c $(COMPAT) # URCU_MB uses urcu.c but -DRCU_MB must be defined -URCU_MB=$(top_srcdir)/urcu.c $(top_srcdir)/urcu-pointer.c $(top_srcdir)/urcu-call-rcu.c $(top_srcdir)/wfqueue.c $(COMPAT) +URCU_MB=$(top_srcdir)/urcu.c $(top_srcdir)/urcu-pointer.c $(top_srcdir)/wfqueue.c $(COMPAT) # URCU_SIGNAL uses urcu.c but -DRCU_SIGNAL must be defined -URCU_SIGNAL=$(top_srcdir)/urcu.c $(top_srcdir)/urcu-pointer.c $(top_srcdir)/urcu-call-rcu.c $(top_srcdir)/wfqueue.c $(COMPAT) -URCU_BP=$(top_srcdir)/urcu-bp.c $(top_srcdir)/urcu-pointer.c $(top_srcdir)/urcu-call-rcu.c $(top_srcdir)/wfqueue.c $(COMPAT) -URCU_DEFER=$(top_srcdir)/urcu.c $(top_srcdir)/urcu-defer.c $(top_srcdir)/urcu-pointer.c $(top_srcdir)/urcu-call-rcu.c $(top_srcdir)/wfqueue.c $(COMPAT) +URCU_SIGNAL=$(top_srcdir)/urcu.c $(top_srcdir)/urcu-pointer.c $(top_srcdir)/wfqueue.c $(COMPAT) +URCU_BP=$(top_srcdir)/urcu-bp.c $(top_srcdir)/urcu-pointer.c $(top_srcdir)/wfqueue.c $(COMPAT) +URCU_DEFER=$(top_srcdir)/urcu.c $(top_srcdir)/urcu-defer.c $(top_srcdir)/urcu-pointer.c $(top_srcdir)/wfqueue.c $(COMPAT) URCU_LIB=$(top_builddir)/liburcu.la URCU_QSBR_LIB=$(top_builddir)/liburcu-qsbr.la URCU_MB_LIB=$(top_builddir)/liburcu-mb.la URCU_SIGNAL_LIB=$(top_builddir)/liburcu-signal.la URCU_BP_LIB=$(top_builddir)/liburcu-bp.la -URCU_CALL_LIB=$(top_builddir)/liburcu-call.la WFQUEUE_LIB=$(top_builddir)/libwfqueue.la WFSTACK_LIB=$(top_builddir)/libwfstack.la RCULFQUEUE_LIB=$(top_builddir)/librculfqueue.la @@ -95,24 +94,24 @@ test_perthreadlock_SOURCES = test_perthreadlock.c $(URCU_SIGNAL) rcutorture_urcu_SOURCES = urcutorture.c -rcutorture_urcu_CFLAGS = -DTORTURE_URCU $(AM_CFLAGS) -rcutorture_urcu_LDADD = $(URCU) $(URCU_CALL_LIB) $(WFQUEUE_LIB) +rcutorture_urcu_CFLAGS = -DRCU_MEMBARRIER $(AM_CFLAGS) +rcutorture_urcu_LDADD = $(URCU) $(WFQUEUE_LIB) rcutorture_urcu_mb_SOURCES = urcutorture.c -rcutorture_urcu_mb_CFLAGS = -DTORTURE_URCU_MB $(AM_CFLAGS) -rcutorture_urcu_mb_LDADD = $(URCU_MB_LIB) $(URCU_CALL_LIB) $(WFQUEUE_LIB) +rcutorture_urcu_mb_CFLAGS = -DRCU_MB $(AM_CFLAGS) +rcutorture_urcu_mb_LDADD = $(URCU_MB_LIB) $(WFQUEUE_LIB) rcutorture_qsbr_SOURCES = urcutorture.c -rcutorture_qsbr_CFLAGS = -DTORTURE_QSBR $(AM_CFLAGS) -rcutorture_qsbr_LDADD = $(URCU_QSBR_LIB) $(URCU_CALL_LIB) $(WFQUEUE_LIB) +rcutorture_qsbr_CFLAGS = -DRCU_QSBR $(AM_CFLAGS) +rcutorture_qsbr_LDADD = $(URCU_QSBR_LIB) $(WFQUEUE_LIB) rcutorture_urcu_signal_SOURCES = urcutorture.c -rcutorture_urcu_signal_CFLAGS = -DTORTURE_URCU_SIGNAL $(AM_CFLAGS) -rcutorture_urcu_signal_LDADD = $(URCU_SIGNAL_LIB) $(URCU_CALL_LIB) $(WFQUEUE_LIB) +rcutorture_urcu_signal_CFLAGS = -DRCU_SIGNAL $(AM_CFLAGS) +rcutorture_urcu_signal_LDADD = $(URCU_SIGNAL_LIB) $(WFQUEUE_LIB) rcutorture_urcu_bp_SOURCES = urcutorture.c -rcutorture_urcu_bp_CFLAGS = -DTORTURE_URCU_BP $(AM_CFLAGS) -rcutorture_urcu_bp_LDADD = $(URCU_BP_LIB) $(URCU_CALL_LIB) $(WFQUEUE_LIB) +rcutorture_urcu_bp_CFLAGS = -DRCU_BP $(AM_CFLAGS) +rcutorture_urcu_bp_LDADD = $(URCU_BP_LIB) $(WFQUEUE_LIB) test_mutex_SOURCES = test_mutex.c $(URCU) diff --git a/tests/rcutorture.h b/tests/rcutorture.h index 66fdd7f..aba74b0 100644 --- a/tests/rcutorture.h +++ b/tests/rcutorture.h @@ -66,7 +66,6 @@ */ #include -#include "../urcu-call-rcu.h" DEFINE_PER_THREAD(long long, n_reads_pt); DEFINE_PER_THREAD(long long, n_updates_pt); diff --git a/tests/urcutorture.c b/tests/urcutorture.c index 63fa386..a098d87 100644 --- a/tests/urcutorture.c +++ b/tests/urcutorture.c @@ -8,22 +8,19 @@ #include "api.h" #define _LGPL_SOURCE -#ifdef TORTURE_RCU_MEMBARRIER -#define RCU_MEMBARRIER +#ifdef RCU_MEMBARRIER #include #endif -#ifdef TORTURE_URCU_SIGNAL -#define RCU_SIGNAL +#ifdef RCU_SIGNAL #include #endif -#ifdef TORTURE_URCU_MB -#define RCU_MB +#ifdef RCU_MB #include #endif -#ifdef TORTURE_QSBR +#ifdef RCU_QSBR #include #endif -#ifdef TORTURE_URCU_BP +#ifdef RCU_BP #include #endif diff --git a/urcu-bp-map.h b/urcu-bp-map.h new file mode 100644 index 0000000..6321802 --- /dev/null +++ b/urcu-bp-map.h @@ -0,0 +1,61 @@ +#ifndef _URCU_BP_MAP_H +#define _URCU_BP_MAP_H + +/* + * urcu-map.h + * + * Userspace RCU header -- name mapping to allow multiple flavors to be + * used in the same executable. + * + * Copyright (c) 2009 Mathieu Desnoyers + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. + * + * LGPL-compatible code should include this header with : + * + * #define _LGPL_SOURCE + * #include + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * IBM's contributions to this file may be relicensed under LGPLv2 or later. + */ + +/* Mapping macros to allow multiple flavors in a single binary. */ + +#define rcu_read_lock rcu_read_lock_bp +#define _rcu_read_lock _rcu_read_lock_bp +#define rcu_read_unlock rcu_read_unlock_bp +#define _rcu_read_unlock _rcu_read_unlock_bp +#define rcu_register_thread rcu_register_thread_bp +#define rcu_unregister_thread rcu_unregister_thread_bp +#define rcu_init rcu_init_bp +#define rcu_exit rcu_exit_bp +#define synchronize_rcu synchronize_rcu_bp +#define rcu_reader rcu_reader_bp +#define rcu_gp_ctr rcu_gp_ctr_bp + +#define get_cpu_call_rcu_data get_cpu_call_rcu_data_bp +#define get_call_rcu_thread get_call_rcu_thread_bp +#define create_call_rcu_data create_call_rcu_data_bp +#define set_cpu_call_rcu_data set_cpu_call_rcu_data_bp +#define get_default_call_rcu_data get_default_call_rcu_data_bp +#define get_call_rcu_data get_call_rcu_data_bp +#define get_thread_call_rcu_data get_thread_call_rcu_data_bp +#define set_thread_call_rcu_data set_thread_call_rcu_data_bp +#define create_all_cpu_call_rcu_data create_all_cpu_call_rcu_data_bp +#define free_all_cpu_call_rcu_data free_all_cpu_call_rcu_data_bp +#define call_rcu call_rcu_bp + +#endif /* _URCU_BP_MAP_H */ diff --git a/urcu-bp.c b/urcu-bp.c index 04bb675..5474f9f 100644 --- a/urcu-bp.c +++ b/urcu-bp.c @@ -35,6 +35,8 @@ #include #include +#include "urcu-bp-map.h" + #include "urcu-bp-static.h" /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ #include "urcu-bp.h" @@ -375,3 +377,5 @@ void rcu_bp_after_fork_child(void) ret = pthread_sigmask(SIG_SETMASK, &oldmask, NULL); assert(!ret); } + +#include "urcu-call-rcu-impl.h" diff --git a/urcu-bp.h b/urcu-bp.h index d92fbd1..fdf885c 100644 --- a/urcu-bp.h +++ b/urcu-bp.h @@ -46,6 +46,8 @@ extern "C" { #endif +#include "urcu-bp-map.h" + /* * Important ! * @@ -69,8 +71,8 @@ extern "C" { * * Mark the beginning and end of a read-side critical section. */ -#define rcu_read_lock() _rcu_read_lock() -#define rcu_read_unlock() _rcu_read_unlock() +#define rcu_read_lock_bp() _rcu_read_lock() +#define rcu_read_unlock_bp() _rcu_read_unlock() #else /* !_LGPL_SOURCE */ @@ -115,4 +117,6 @@ static inline void rcu_init(void) } #endif +#include "urcu-call-rcu.h" + #endif /* _URCU_BP_H */ diff --git a/urcu-call-rcu.c b/urcu-call-rcu-impl.h similarity index 99% rename from urcu-call-rcu.c rename to urcu-call-rcu-impl.h index 9cc56c5..9fa6aa6 100644 --- a/urcu-call-rcu.c +++ b/urcu-call-rcu-impl.h @@ -69,8 +69,6 @@ static pthread_mutex_t call_rcu_mutex = PTHREAD_MUTEX_INITIALIZER; static struct call_rcu_data *default_call_rcu_data; -extern void synchronize_rcu(void); - /* * If the sched_getcpu() and sysconf(_SC_NPROCESSORS_CONF) calls are * available, then we can have call_rcu threads assigned to individual diff --git a/urcu-map.h b/urcu-map.h new file mode 100644 index 0000000..eccaac2 --- /dev/null +++ b/urcu-map.h @@ -0,0 +1,117 @@ +#ifndef _URCU_MAP_H +#define _URCU_MAP_H + +/* + * urcu-map.h + * + * Userspace RCU header -- name mapping to allow multiple flavors to be + * used in the same executable. + * + * Copyright (c) 2009 Mathieu Desnoyers + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. + * + * LGPL-compatible code should include this header with : + * + * #define _LGPL_SOURCE + * #include + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * IBM's contributions to this file may be relicensed under LGPLv2 or later. + */ + +/* Mapping macros to allow multiple flavors in a single binary. */ + +#ifdef RCU_MEMBARRIER + +#define rcu_read_lock rcu_read_lock_memb +#define _rcu_read_lock _rcu_read_lock_memb +#define rcu_read_unlock rcu_read_unlock_memb +#define _rcu_read_unlock _rcu_read_unlock_memb +#define rcu_register_thread rcu_register_thread_memb +#define rcu_unregister_thread rcu_unregister_thread_memb +#define rcu_init rcu_init_memb +#define rcu_exit rcu_exit_memb +#define synchronize_rcu synchronize_rcu_memb +#define rcu_reader rcu_reader_memb +#define rcu_gp_ctr rcu_gp_ctr_memb + +#define get_cpu_call_rcu_data get_cpu_call_rcu_data_memb +#define get_call_rcu_thread get_call_rcu_thread_memb +#define create_call_rcu_data create_call_rcu_data_memb +#define set_cpu_call_rcu_data set_cpu_call_rcu_data_memb +#define get_default_call_rcu_data get_default_call_rcu_data_memb +#define get_call_rcu_data get_call_rcu_data_memb +#define get_thread_call_rcu_data get_thread_call_rcu_data_memb +#define set_thread_call_rcu_data set_thread_call_rcu_data_memb +#define create_all_cpu_call_rcu_data create_all_cpu_call_rcu_data_memb +#define free_all_cpu_call_rcu_data free_all_cpu_call_rcu_data_memb +#define call_rcu call_rcu_memb + +#elif defined(RCU_SIGNAL) + +#define rcu_read_lock rcu_read_lock_sig +#define _rcu_read_lock _rcu_read_lock_sig +#define rcu_read_unlock rcu_read_unlock_sig +#define _rcu_read_unlock _rcu_read_unlock_sig +#define rcu_register_thread rcu_register_thread_sig +#define rcu_unregister_thread rcu_unregister_thread_sig +#define rcu_init rcu_init_sig +#define rcu_exit rcu_exit_sig +#define synchronize_rcu synchronize_rcu_sig +#define rcu_reader rcu_reader_sig +#define rcu_gp_ctr rcu_gp_ctr_sig + +#define get_cpu_call_rcu_data get_cpu_call_rcu_data_sig +#define get_call_rcu_thread get_call_rcu_thread_sig +#define create_call_rcu_data create_call_rcu_data_sig +#define set_cpu_call_rcu_data set_cpu_call_rcu_data_sig +#define get_default_call_rcu_data get_default_call_rcu_data_sig +#define get_call_rcu_data get_call_rcu_data_sig +#define get_thread_call_rcu_data get_thread_call_rcu_data_sig +#define set_thread_call_rcu_data set_thread_call_rcu_data_sig +#define create_all_cpu_call_rcu_data create_all_cpu_call_rcu_data_sig +#define free_all_cpu_call_rcu_data free_all_cpu_call_rcu_data_sig +#define call_rcu call_rcu_sig + +#elif defined(RCU_MB) + +#define rcu_read_lock rcu_read_lock_mb +#define _rcu_read_lock _rcu_read_lock_mb +#define rcu_read_unlock rcu_read_unlock_mb +#define _rcu_read_unlock _rcu_read_unlock_mb +#define rcu_register_thread rcu_register_thread_mb +#define rcu_unregister_thread rcu_unregister_thread_mb +#define rcu_init rcu_init_mb +#define rcu_exit rcu_exit_mb +#define synchronize_rcu synchronize_rcu_mb +#define rcu_reader rcu_reader_mb +#define rcu_gp_ctr rcu_gp_ctr_mb + +#define get_cpu_call_rcu_data get_cpu_call_rcu_data_mb +#define get_call_rcu_thread get_call_rcu_thread_mb +#define create_call_rcu_data create_call_rcu_data_mb +#define set_cpu_call_rcu_data set_cpu_call_rcu_data_mb +#define get_default_call_rcu_data get_default_call_rcu_data_mb +#define get_call_rcu_data get_call_rcu_data_mb +#define get_thread_call_rcu_data get_thread_call_rcu_data_mb +#define set_thread_call_rcu_data set_thread_call_rcu_data_mb +#define create_all_cpu_call_rcu_data create_all_cpu_call_rcu_data_mb +#define free_all_cpu_call_rcu_data free_all_cpu_call_rcu_data_mb +#define call_rcu call_rcu_mb + +#endif + +#endif /* _URCU_MAP_H */ diff --git a/urcu-qsbr-map.h b/urcu-qsbr-map.h new file mode 100644 index 0000000..2bce1b6 --- /dev/null +++ b/urcu-qsbr-map.h @@ -0,0 +1,63 @@ +#ifndef _URCU_QSBR_MAP_H +#define _URCU_QSBR_MAP_H + +/* + * urcu-map.h + * + * Userspace RCU header -- name mapping to allow multiple flavors to be + * used in the same executable. + * + * Copyright (c) 2009 Mathieu Desnoyers + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. + * + * LGPL-compatible code should include this header with : + * + * #define _LGPL_SOURCE + * #include + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * IBM's contributions to this file may be relicensed under LGPLv2 or later. + */ + +/* Mapping macros to allow multiple flavors in a single binary. */ + +#define rcu_read_lock rcu_read_lock_qsbr +#define _rcu_read_lock _rcu_read_lock_qsbr +#define rcu_read_unlock rcu_read_unlock_qsbr +#define _rcu_read_unlock _rcu_read_unlock_qsbr +#define rcu_quiescent_state rcu_quiescent_state_qsbr +#define _rcu_quiescent_state _rcu_quiescent_state_qsbr +#define rcu_thread_offline rcu_thread_offline_qsbr +#define rcu_thread_online rcu_thread_online_qsbr +#define rcu_register_thread rcu_register_thread_qsbr +#define rcu_unregister_thread rcu_unregister_thread_qsbr +#define rcu_exit rcu_exit_qsbr +#define synchronize_rcu synchronize_rcu_qsbr +#define rcu_reader rcu_reader_qsbr +#define rcu_gp_ctr rcu_gp_ctr_qsbr + +#define get_cpu_call_rcu_data get_cpu_call_rcu_data_qsbr +#define get_call_rcu_thread get_call_rcu_thread_qsbr +#define create_call_rcu_data create_call_rcu_data_qsbr +#define set_cpu_call_rcu_data set_cpu_call_rcu_data_qsbr +#define get_default_call_rcu_data get_default_call_rcu_data_qsbr +#define get_call_rcu_data get_call_rcu_data_qsbr +#define get_thread_call_rcu_data get_thread_call_rcu_data_qsbr +#define set_thread_call_rcu_data set_thread_call_rcu_data_qsbr +#define create_all_cpu_call_rcu_data create_all_cpu_call_rcu_data_qsbr +#define call_rcu call_rcu_qsbr + +#endif /* _URCU_QSBR_MAP_H */ diff --git a/urcu-qsbr.c b/urcu-qsbr.c index 69effd5..8dcad33 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -32,6 +32,8 @@ #include #include +#include "urcu-qsbr-map.h" + #define BUILD_QSBR_LIB #include "urcu-qsbr-static.h" /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ @@ -121,10 +123,11 @@ static void update_counter_and_wait(void) #endif /* !(CAA_BITS_PER_LONG < 64) */ /* - * Must commit rcu_gp_ctr update to memory before waiting for quiescent - * state. Failure to do so could result in the writer waiting forever - * while new readers are always accessing data (no progress). Enforce - * compiler-order of store to rcu_gp_ctr before load rcu_reader ctr. + * Must commit rcu_gp_ctr update to memory before waiting for + * quiescent state. Failure to do so could result in the writer + * waiting forever while new readers are always accessing data + * (no progress). Enforce compiler-order of store to rcu_gp_ctr + * before load rcu_reader ctr. */ cmm_barrier(); @@ -194,8 +197,8 @@ void synchronize_rcu(void) /* * Mark the writer thread offline to make sure we don't wait for - * our own quiescent state. This allows using synchronize_rcu() in - * threads registered as readers. + * our own quiescent state. This allows using synchronize_rcu() + * in threads registered as readers. */ if (was_online) CMM_STORE_SHARED(rcu_reader.ctr, 0); @@ -212,10 +215,11 @@ void synchronize_rcu(void) /* * Must finish waiting for quiescent state for parity 0 before - * committing next rcu_gp_ctr update to memory. Failure to do so could - * result in the writer waiting forever while new readers are always - * accessing data (no progress). Enforce compiler-order of load - * rcu_reader ctr before store to rcu_gp_ctr. + * committing next rcu_gp_ctr update to memory. Failure to + * do so could result in the writer waiting forever while new + * readers are always accessing data (no progress). Enforce + * compiler-order of load rcu_reader ctr before store to + * rcu_gp_ctr. */ cmm_barrier(); @@ -238,7 +242,8 @@ out: * freed. */ if (was_online) - _CMM_STORE_SHARED(rcu_reader.ctr, CMM_LOAD_SHARED(rcu_gp_ctr)); + _CMM_STORE_SHARED(rcu_reader.ctr, + CMM_LOAD_SHARED(rcu_gp_ctr)); cmm_smp_mb(); } #else /* !(CAA_BITS_PER_LONG < 64) */ @@ -250,8 +255,8 @@ void synchronize_rcu(void) /* * Mark the writer thread offline to make sure we don't wait for - * our own quiescent state. This allows using synchronize_rcu() in - * threads registered as readers. + * our own quiescent state. This allows using synchronize_rcu() + * in threads registered as readers. */ cmm_smp_mb(); if (was_online) @@ -265,7 +270,8 @@ out: mutex_unlock(&rcu_gp_lock); if (was_online) - _CMM_STORE_SHARED(rcu_reader.ctr, CMM_LOAD_SHARED(rcu_gp_ctr)); + _CMM_STORE_SHARED(rcu_reader.ctr, + CMM_LOAD_SHARED(rcu_gp_ctr)); cmm_smp_mb(); } #endif /* !(CAA_BITS_PER_LONG < 64) */ @@ -326,3 +332,5 @@ void rcu_exit(void) { assert(cds_list_empty(®istry)); } + +#include "urcu-call-rcu-impl.h" diff --git a/urcu-qsbr.h b/urcu-qsbr.h index 116fd77..984d70c 100644 --- a/urcu-qsbr.h +++ b/urcu-qsbr.h @@ -40,6 +40,8 @@ extern "C" { #endif +#include "urcu-qsbr-map.h" + /* * Important ! * @@ -62,15 +64,15 @@ extern "C" { * rcu_read_unlock() * * Mark the beginning and end of a read-side critical section. - * DON'T FORGET TO USE rcu_register_thread/rcu_unregister_thread() FOR EACH - * THREAD WITH READ-SIDE CRITICAL SECTION. + * DON'T FORGET TO USE rcu_register_thread/rcu_unregister_thread() + * FOR EACH THREAD WITH READ-SIDE CRITICAL SECTION. */ -#define rcu_read_lock() _rcu_read_lock() -#define rcu_read_unlock() _rcu_read_unlock() +#define rcu_read_lock_qsbr() _rcu_read_lock() +#define rcu_read_unlock_qsbr() _rcu_read_unlock() -#define rcu_quiescent_state() _rcu_quiescent_state() -#define rcu_thread_offline() _rcu_thread_offline() -#define rcu_thread_online() _rcu_thread_online() +#define rcu_quiescent_state_qsbr() _rcu_quiescent_state() +#define rcu_thread_offline_qsbr() _rcu_thread_offline() +#define rcu_thread_online_qsbr() _rcu_thread_online() #else /* !_LGPL_SOURCE */ @@ -122,4 +124,6 @@ extern void rcu_unregister_thread(void); } #endif +#include "urcu-call-rcu.h" + #endif /* _URCU_QSBR_H */ diff --git a/urcu.c b/urcu.c index e529ac0..4ee9e3b 100644 --- a/urcu.c +++ b/urcu.c @@ -33,6 +33,8 @@ #include #include +#include "urcu-map.h" + #include "urcu-static.h" /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ #include "urcu.h" @@ -428,4 +430,7 @@ void rcu_exit(void) assert(act.sa_sigaction == sigrcu_handler); assert(cds_list_empty(®istry)); } + #endif /* #ifdef RCU_SIGNAL */ + +#include "urcu-call-rcu-impl.h" diff --git a/urcu.h b/urcu.h index c6c54e7..00d9b75 100644 --- a/urcu.h +++ b/urcu.h @@ -43,12 +43,14 @@ extern "C" { #endif +#include "urcu-map.h" + /* * Important ! * * Each thread containing read-side critical sections must be registered - * with rcu_register_thread() before calling rcu_read_lock(). - * rcu_unregister_thread() should be called before the thread exits. + * with rcu_register_thread_mb() before calling rcu_read_lock_mb(). + * rcu_unregister_thread_mb() should be called before the thread exits. */ #ifdef _LGPL_SOURCE @@ -68,8 +70,16 @@ extern "C" { * DON'T FORGET TO USE RCU_REGISTER/UNREGISTER_THREAD() FOR EACH THREAD WITH * READ-SIDE CRITICAL SECTION. */ -#define rcu_read_lock() _rcu_read_lock() -#define rcu_read_unlock() _rcu_read_unlock() +#ifdef RCU_MEMBARRIER +#define rcu_read_lock_memb() _rcu_read_lock() +#define rcu_read_unlock_memb() _rcu_read_unlock() +#elif defined(RCU_SIGNAL) +#define rcu_read_lock_sig() _rcu_read_lock() +#define rcu_read_unlock_sig() _rcu_read_unlock() +#elif defined(RCU_MB) +#define rcu_read_lock_mb() _rcu_read_lock() +#define rcu_read_unlock_mb() _rcu_read_unlock() +#endif #else /* !_LGPL_SOURCE */ @@ -100,4 +110,6 @@ extern void rcu_init(void); } #endif +#include "urcu-call-rcu.h" + #endif /* _URCU_H */ -- 2.34.1