$(top_srcdir)/urcu/map/*.h \
$(top_srcdir)/urcu/static/*.h \
urcu/rand-compat.h \
- urcu/tls-compat.h
+ urcu/tls-compat.h urcu/debug.h
nobase_nodist_include_HEADERS = urcu/arch.h urcu/uatomic.h urcu/config.h
dist_noinst_HEADERS = urcu-die.h urcu-wait.h
* This is required to permit relinking with newer versions of the library.
*/
-#ifdef DEBUG_RCU
-#define rcu_assert(args...) assert(args)
-#else
-#define rcu_assert(args...)
-#endif
-
/*
* defer queue.
* Contains pointers. Encoded to save space when same callback is often used.
assert(URCU_TLS(rcu_reader).ctr == 0);
mutex_lock(&rcu_registry_lock);
+ assert(!URCU_TLS(rcu_reader).registered);
+ URCU_TLS(rcu_reader).registered = 1;
cds_list_add(&URCU_TLS(rcu_reader).node, ®istry);
mutex_unlock(&rcu_registry_lock);
_rcu_thread_online();
* with a waiting writer.
*/
_rcu_thread_offline();
+ assert(URCU_TLS(rcu_reader).registered);
+ URCU_TLS(rcu_reader).registered = 0;
mutex_lock(&rcu_registry_lock);
cds_list_del(&URCU_TLS(rcu_reader).node);
mutex_unlock(&rcu_registry_lock);
assert(!(URCU_TLS(rcu_reader).ctr & RCU_GP_CTR_NEST_MASK));
mutex_lock(&rcu_registry_lock);
+ assert(!URCU_TLS(rcu_reader).registered);
+ URCU_TLS(rcu_reader).registered = 1;
rcu_init(); /* In case gcc does not support constructor attribute */
cds_list_add(&URCU_TLS(rcu_reader).node, ®istry);
mutex_unlock(&rcu_registry_lock);
void rcu_unregister_thread(void)
{
mutex_lock(&rcu_registry_lock);
+ assert(URCU_TLS(rcu_reader).registered);
+ URCU_TLS(rcu_reader).registered = 0;
cds_list_del(&URCU_TLS(rcu_reader).node);
mutex_unlock(&rcu_registry_lock);
}
--- /dev/null
+#ifndef _URCU_DEBUG_H
+#define _URCU_DEBUG_H
+
+/*
+ * urcu/debug.h
+ *
+ * Userspace RCU debugging facilities.
+ *
+ * Copyright (c) 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ */
+
+#include <assert.h>
+
+#ifdef DEBUG_RCU
+#define urcu_assert(...) assert(__VA_ARGS__)
+#else
+#define urcu_assert(...)
+#endif
+
+#endif /* _URCU_DEBUG_H */
#include <urcu/uatomic.h>
#include <urcu/list.h>
#include <urcu/tls-compat.h>
+#include <urcu/debug.h>
/*
* This code section can only be included in LGPL 2.1 compatible source code.
extern "C" {
#endif
-#ifdef DEBUG_RCU
-#define rcu_assert(args...) assert(args)
-#else
-#define rcu_assert(args...)
-#endif
-
enum rcu_state {
RCU_READER_ACTIVE_CURRENT,
RCU_READER_ACTIVE_OLD,
#include <stdlib.h>
#include <pthread.h>
-#include <assert.h>
#include <limits.h>
#include <unistd.h>
#include <stdint.h>
#include <urcu/list.h>
#include <urcu/futex.h>
#include <urcu/tls-compat.h>
+#include <urcu/debug.h>
#ifdef __cplusplus
extern "C" {
* This is required to permit relinking with newer versions of the library.
*/
-#ifdef DEBUG_RCU
-#define rcu_assert(args...) assert(args)
-#else
-#define rcu_assert(args...)
-#endif
-
enum rcu_state {
RCU_READER_ACTIVE_CURRENT,
RCU_READER_ACTIVE_OLD,
struct cds_list_head node __attribute__((aligned(CAA_CACHE_LINE_SIZE)));
int waiting;
pthread_t tid;
+ /* Reader registered flag, for internal checks. */
+ unsigned int registered:1;
};
extern DECLARE_URCU_TLS(struct rcu_reader, rcu_reader);
*/
static inline void _rcu_read_lock(void)
{
- rcu_assert(URCU_TLS(rcu_reader).ctr);
+ urcu_assert(URCU_TLS(rcu_reader).ctr);
}
/*
*/
static inline void _rcu_read_unlock(void)
{
+ urcu_assert(URCU_TLS(rcu_reader).ctr);
}
/*
{
unsigned long gp_ctr;
+ urcu_assert(URCU_TLS(rcu_reader).registered);
if ((gp_ctr = CMM_LOAD_SHARED(rcu_gp.ctr)) == URCU_TLS(rcu_reader).ctr)
return;
_rcu_quiescent_state_update_and_wakeup(gp_ctr);
*/
static inline void _rcu_thread_offline(void)
{
+ urcu_assert(URCU_TLS(rcu_reader).registered);
cmm_smp_mb();
CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, 0);
cmm_smp_mb(); /* write URCU_TLS(rcu_reader).ctr before read futex */
*/
static inline void _rcu_thread_online(void)
{
+ urcu_assert(URCU_TLS(rcu_reader).registered);
cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */
_CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, CMM_LOAD_SHARED(rcu_gp.ctr));
cmm_smp_mb();
#include <urcu/futex.h>
#include <urcu/tls-compat.h>
#include <urcu/rand-compat.h>
+#include <urcu/debug.h>
#ifdef __cplusplus
extern "C" {
RCU_READER_INACTIVE,
};
-#ifdef DEBUG_RCU
-#define rcu_assert(args...) assert(args)
-#else
-#define rcu_assert(args...)
-#endif
-
/*
* RCU memory barrier broadcast group. Currently, only broadcast to all process
* threads is supported (group 0).
/* Data used for registry */
struct cds_list_head node __attribute__((aligned(CAA_CACHE_LINE_SIZE)));
pthread_t tid;
+ /* Reader registered flag, for internal checks. */
+ unsigned int registered:1;
};
extern DECLARE_URCU_TLS(struct rcu_reader, rcu_reader);
{
unsigned long tmp;
+ urcu_assert(URCU_TLS(rcu_reader).registered);
cmm_barrier();
tmp = URCU_TLS(rcu_reader).ctr;
_rcu_read_lock_update(tmp);
{
unsigned long tmp;
+ urcu_assert(URCU_TLS(rcu_reader).registered);
tmp = URCU_TLS(rcu_reader).ctr;
_rcu_read_unlock_update_and_wakeup(tmp);
cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */