Need to link with liburcu-common in addition to urcu flavor.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
$(top_srcdir)/urcu/map/*.h \
$(top_srcdir)/urcu/static/*.h \
urcu/rand-compat.h \
- urcu/tls-compat.h
+ urcu/tls-compat.h urcu/urcu-checker.h
nobase_nodist_include_HEADERS = urcu/arch.h urcu/uatomic.h urcu/config.h
dist_noinst_HEADERS = urcu-die.h urcu-wait.h
# liburcu-common contains wait-free queues (needed by call_rcu) as well
# as futex fallbacks.
#
-liburcu_common_la_SOURCES = wfqueue.c wfcqueue.c wfstack.c $(COMPAT)
+liburcu_common_la_SOURCES = wfqueue.c wfcqueue.c wfstack.c $(COMPAT) \
+ urcu-checker.c
liburcu_la_SOURCES = urcu.c urcu-pointer.c $(COMPAT)
liburcu_la_LIBADD = liburcu-common.la
test_urcu_lfs_rcu_dynlink
URCU_COMMON_LIB=$(top_builddir)/liburcu-common.la
-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_CDS_LIB=$(top_builddir)/liburcu-cds.la
+URCU_LIB=$(top_builddir)/liburcu.la $(URCU_COMMON_LIB)
+URCU_QSBR_LIB=$(top_builddir)/liburcu-qsbr.la $(URCU_COMMON_LIB)
+URCU_MB_LIB=$(top_builddir)/liburcu-mb.la $(URCU_COMMON_LIB)
+URCU_SIGNAL_LIB=$(top_builddir)/liburcu-signal.la $(URCU_COMMON_LIB)
+URCU_BP_LIB=$(top_builddir)/liburcu-bp.la $(URCU_COMMON_LIB)
+URCU_CDS_LIB=$(top_builddir)/liburcu-cds.la $(URCU_COMMON_LIB)
DEBUG_YIELD_LIB=$(builddir)/../common/libdebug-yield.la
noinst_HEADERS = rcutorture.h
URCU_COMMON_LIB=$(top_builddir)/liburcu-common.la
-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_CDS_LIB=$(top_builddir)/liburcu-cds.la
+URCU_LIB=$(top_builddir)/liburcu.la $(URCU_COMMON_LIB)
+URCU_QSBR_LIB=$(top_builddir)/liburcu-qsbr.la $(URCU_COMMON_LIB)
+URCU_MB_LIB=$(top_builddir)/liburcu-mb.la $(URCU_COMMON_LIB)
+URCU_SIGNAL_LIB=$(top_builddir)/liburcu-signal.la $(URCU_COMMON_LIB)
+URCU_BP_LIB=$(top_builddir)/liburcu-bp.la $(URCU_COMMON_LIB)
+URCU_CDS_LIB=$(top_builddir)/liburcu-cds.la $(URCU_COMMON_LIB)
test_urcu_fork_SOURCES = test_urcu_fork.c
test_urcu_fork_LDADD = $(URCU_LIB)
noinst_HEADERS = test_urcu_multiflavor.h
URCU_COMMON_LIB=$(top_builddir)/liburcu-common.la
-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_CDS_LIB=$(top_builddir)/liburcu-cds.la
+URCU_LIB=$(top_builddir)/liburcu.la $(URCU_COMMON_LIB)
+URCU_QSBR_LIB=$(top_builddir)/liburcu-qsbr.la $(URCU_COMMON_LIB)
+URCU_MB_LIB=$(top_builddir)/liburcu-mb.la $(URCU_COMMON_LIB)
+URCU_SIGNAL_LIB=$(top_builddir)/liburcu-signal.la $(URCU_COMMON_LIB)
+URCU_BP_LIB=$(top_builddir)/liburcu-bp.la $(URCU_COMMON_LIB)
+URCU_CDS_LIB=$(top_builddir)/liburcu-cds.la $(URCU_COMMON_LIB)
test_uatomic_SOURCES = test_uatomic.c
test_uatomic_LDADD = $(URCU_COMMON_LIB)
* See LGPL-only urcu/static/urcu-pointer.h for documentation.
*/
-extern void rcu_read_lock(void);
-extern void rcu_read_unlock(void);
+extern void test_rcu_read_lock(void);
+extern void test_rcu_read_unlock(void);
extern int rcu_read_ongoing(void);
extern void *rcu_dereference_sym_bp(void *p);
--- /dev/null
+/*
+ * urcu-checker.c
+ *
+ * Userspace RCU library checker
+ *
+ * Copyright (c) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * 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
+ */
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <urcu/urcu-checker.h>
+#include <urcu/tls-compat.h>
+
+#define URCU_DEBUG_STACK_LEN 10
+
+struct urcu_debug_entry {
+ void *ip;
+ int depth;
+};
+
+struct urcu_debug_stack {
+ struct urcu_debug_entry stack[URCU_DEBUG_STACK_LEN];
+ int stackend;
+};
+
+static DEFINE_URCU_TLS(struct urcu_debug_stack, rcu_debug_stack);
+
+void rcu_read_lock_debug(void)
+{
+ struct urcu_debug_stack *r = &URCU_TLS(rcu_debug_stack);
+
+ r->stack[r->stackend++].ip = __builtin_return_address(0);
+}
+
+void rcu_read_unlock_debug(void)
+{
+ struct urcu_debug_stack *r = &URCU_TLS(rcu_debug_stack);
+
+ assert(r->stackend != 0);
+ r->stack[--r->stackend].ip = NULL;
+}
+
+void rcu_read_ongoing_check_debug(const char *func)
+{
+ struct urcu_debug_stack *r = &URCU_TLS(rcu_debug_stack);
+
+ if (r->stackend == 0) {
+ fprintf(stderr, "URCU LOCKED CHECK failure: %p\n",
+ __builtin_return_address(0));
+ abort();
+ }
+}
#include <urcu/compiler.h>
#include <urcu/arch.h>
#include <urcu/uatomic.h>
+#include <urcu/urcu-checker.h>
#ifdef __cplusplus
extern "C" {
* Fetch a RCU-protected pointer. Typically used to copy the variable ptr to a
* local variable.
*/
-#define rcu_dereference _rcu_dereference
+#define rcu_dereference(p) \
+ ({ \
+ rcu_read_ongoing_check_debug(__func__); \
+ _rcu_dereference(p); \
+ })
/*
* type *rcu_cmpxchg_pointer(type **ptr, type *new, type *old)
#endif /* !RCU_DEBUG */
+#define test_rcu_read_lock rcu_read_lock_qsbr
+#define test_rcu_read_unlock rcu_read_unlock_qsbr
+
extern int rcu_read_ongoing(void);
extern void rcu_quiescent_state(void);
extern void rcu_thread_offline(void);
return _rcu_read_ongoing();
}
+
+
void rcu_register_thread(void)
{
URCU_TLS(rcu_reader).tid = pthread_self();
#include <stdlib.h>
#include <pthread.h>
+#include <urcu/tls-compat.h>
+#include <stdio.h>
+#include <assert.h>
/*
* See urcu-pointer.h and urcu/static/urcu-pointer.h for pointer
#include <urcu/uatomic.h>
#include <urcu/list.h>
#include <urcu/tls-compat.h>
+#include <urcu/urcu-checker.h>
/*
* This code section can only be included in LGPL 2.1 compatible source code.
{
unsigned long tmp;
+ rcu_read_lock_debug();
if (caa_unlikely(!URCU_TLS(rcu_reader)))
rcu_bp_register(); /* If not yet registered. */
cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */
cmm_smp_mb();
_CMM_STORE_SHARED(URCU_TLS(rcu_reader)->ctr, URCU_TLS(rcu_reader)->ctr - RCU_GP_COUNT);
cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */
+ rcu_read_unlock_debug();
}
/*
#include <urcu/list.h>
#include <urcu/futex.h>
#include <urcu/tls-compat.h>
+#include <urcu/urcu-checker.h>
#ifdef __cplusplus
extern "C" {
*/
static inline void _rcu_read_lock(void)
{
+ rcu_read_lock_debug();
rcu_assert(URCU_TLS(rcu_reader).ctr);
}
*/
static inline void _rcu_read_unlock(void)
{
+ rcu_read_unlock_debug();
}
/*
#include <urcu/futex.h>
#include <urcu/tls-compat.h>
#include <urcu/rand-compat.h>
+#include <urcu/urcu-checker.h>
#ifdef __cplusplus
extern "C" {
{
unsigned long tmp;
+ rcu_read_lock_debug();
cmm_barrier();
tmp = URCU_TLS(rcu_reader).ctr;
_rcu_read_lock_update(tmp);
tmp = URCU_TLS(rcu_reader).ctr;
_rcu_read_unlock_update_and_wakeup(tmp);
cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */
+ rcu_read_unlock_debug();
}
/*
--- /dev/null
+#ifndef _URCU_CHECKER_H
+#define _URCU_CHECKER_H
+
+/*
+ * urcu-checker.h
+ *
+ * Userspace RCU checker header
+ *
+ * Copyright (c) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * LGPL-compatible code should include this header with :
+ *
+ * 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
+ */
+
+void rcu_read_lock_debug(void);
+void rcu_read_unlock_debug(void);
+void rcu_read_ongoing_check_debug(const char *func);
+
+#endif /* _URCU_CHECKER_H */