#include <stdint.h>
#include <string.h>
#include <errno.h>
+#include <stdbool.h>
#include <poll.h>
-#include "urcu/arch.h"
-#include "urcu/wfcqueue.h"
-#include "urcu/map/urcu.h"
-#include "urcu/static/urcu.h"
-#include "urcu-pointer.h"
-#include "urcu/tls-compat.h"
+#include <urcu/arch.h>
+#include <urcu/wfcqueue.h>
+#include <urcu/map/urcu.h>
+#include <urcu/static/urcu.h>
+#include <urcu/pointer.h>
+#include <urcu/tls-compat.h>
#include "urcu-die.h"
#include "urcu-wait.h"
+#include "urcu-utils.h"
+#define URCU_API_MAP
/* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */
#undef _LGPL_SOURCE
-#include "urcu.h"
+#include <urcu/urcu.h>
#define _LGPL_SOURCE
/*
#endif
enum membarrier_cmd {
- MEMBARRIER_CMD_QUERY = 0,
- MEMBARRIER_CMD_SHARED = (1 << 0),
+ MEMBARRIER_CMD_QUERY = 0,
+ MEMBARRIER_CMD_SHARED = (1 << 0),
+ /* reserved for MEMBARRIER_CMD_SHARED_EXPEDITED (1 << 1) */
+ /* reserved for MEMBARRIER_CMD_PRIVATE (1 << 2) */
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3),
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4),
};
#ifdef RCU_MEMBARRIER
static int init_done;
+static int urcu_memb_has_sys_membarrier_private_expedited;
+
#ifndef CONFIG_RCU_FORCE_SYS_MEMBARRIER
-int rcu_has_sys_membarrier_memb;
+/*
+ * Explicitly initialize to zero because we can't alias a non-static
+ * uninitialized variable.
+ */
+int urcu_memb_has_sys_membarrier = 0;
+URCU_ATTR_ALIAS("urcu_memb_has_sys_membarrier")
+extern int rcu_has_sys_membarrier_memb;
#endif
void __attribute__((constructor)) rcu_init(void);
void rcu_init(void)
{
}
+URCU_ATTR_ALIAS(urcu_stringify(rcu_init))
+void alias_rcu_init(void);
#endif
#ifdef RCU_SIGNAL
* rcu_registry_lock may nest inside rcu_gp_lock.
*/
static pthread_mutex_t rcu_registry_lock = PTHREAD_MUTEX_INITIALIZER;
-struct rcu_gp rcu_gp = { .ctr = RCU_GP_COUNT };
+struct urcu_gp rcu_gp = { .ctr = URCU_GP_COUNT };
+URCU_ATTR_ALIAS(urcu_stringify(rcu_gp))
+extern struct urcu_gp alias_rcu_gp;
/*
* Written to only by each individual reader. Read by both the reader and the
* writers.
*/
-DEFINE_URCU_TLS_IE(struct rcu_reader, rcu_reader);
+DEFINE_URCU_TLS(struct urcu_reader, rcu_reader);
+DEFINE_URCU_TLS_ALIAS(struct urcu_reader, rcu_reader, alias_rcu_reader);
static CDS_LIST_HEAD(registry);
#ifdef RCU_MEMBARRIER
static void smp_mb_master(void)
{
- if (caa_likely(rcu_has_sys_membarrier_memb))
- (void) membarrier(MEMBARRIER_CMD_SHARED, 0);
- else
+ if (caa_likely(urcu_memb_has_sys_membarrier)) {
+ if (membarrier(urcu_memb_has_sys_membarrier_private_expedited ?
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED :
+ MEMBARRIER_CMD_SHARED, 0))
+ urcu_die(errno);
+ } else {
cmm_smp_mb();
+ }
}
#endif
#ifdef RCU_SIGNAL
static void force_mb_all_readers(void)
{
- struct rcu_reader *index;
+ struct urcu_reader *index;
/*
* Ask for each threads to execute a cmm_smp_mb() so we can consider the
struct cds_list_head *qsreaders)
{
unsigned int wait_loops = 0;
- struct rcu_reader *index, *tmp;
+ struct urcu_reader *index, *tmp;
#ifdef HAS_INCOHERENT_CACHES
unsigned int wait_gp_loops = 0;
#endif /* HAS_INCOHERENT_CACHES */
}
cds_list_for_each_entry_safe(index, tmp, input_readers, node) {
- switch (rcu_reader_state(&index->ctr)) {
- case RCU_READER_ACTIVE_CURRENT:
+ switch (urcu_common_reader_state(&rcu_gp, &index->ctr)) {
+ case URCU_READER_ACTIVE_CURRENT:
if (cur_snap_readers) {
cds_list_move(&index->node,
cur_snap_readers);
break;
}
/* Fall-through */
- case RCU_READER_INACTIVE:
+ case URCU_READER_INACTIVE:
cds_list_move(&index->node, qsreaders);
break;
- case RCU_READER_ACTIVE_OLD:
+ case URCU_READER_ACTIVE_OLD:
/*
* Old snapshot. Leaving node in
* input_readers will make us busy-loop
cmm_smp_mb();
/* Switch parity: 0 -> 1, 1 -> 0 */
- CMM_STORE_SHARED(rcu_gp.ctr, rcu_gp.ctr ^ RCU_GP_CTR_PHASE);
+ CMM_STORE_SHARED(rcu_gp.ctr, rcu_gp.ctr ^ URCU_GP_CTR_PHASE);
/*
* Must commit rcu_gp.ctr update to memory before waiting for quiescent
*/
urcu_wake_all_waiters(&waiters);
}
+URCU_ATTR_ALIAS(urcu_stringify(synchronize_rcu))
+void alias_synchronize_rcu();
/*
* library wrappers to be used by non-LGPL compatible source code.
{
_rcu_read_lock();
}
+URCU_ATTR_ALIAS(urcu_stringify(rcu_read_lock))
+void alias_rcu_read_lock();
void rcu_read_unlock(void)
{
_rcu_read_unlock();
}
+URCU_ATTR_ALIAS(urcu_stringify(rcu_read_unlock))
+void alias_rcu_read_unlock();
int rcu_read_ongoing(void)
{
return _rcu_read_ongoing();
}
+URCU_ATTR_ALIAS(urcu_stringify(rcu_read_ongoing))
+void alias_rcu_read_ongoing();
void rcu_register_thread(void)
{
URCU_TLS(rcu_reader).tid = pthread_self();
assert(URCU_TLS(rcu_reader).need_mb == 0);
- assert(!(URCU_TLS(rcu_reader).ctr & RCU_GP_CTR_NEST_MASK));
+ assert(!(URCU_TLS(rcu_reader).ctr & URCU_GP_CTR_NEST_MASK));
mutex_lock(&rcu_registry_lock);
assert(!URCU_TLS(rcu_reader).registered);
cds_list_add(&URCU_TLS(rcu_reader).node, ®istry);
mutex_unlock(&rcu_registry_lock);
}
+URCU_ATTR_ALIAS(urcu_stringify(rcu_register_thread))
+void alias_rcu_register_thread();
void rcu_unregister_thread(void)
{
cds_list_del(&URCU_TLS(rcu_reader).node);
mutex_unlock(&rcu_registry_lock);
}
+URCU_ATTR_ALIAS(urcu_stringify(rcu_unregister_thread))
+void alias_rcu_unregister_thread();
#ifdef RCU_MEMBARRIER
#ifdef CONFIG_RCU_FORCE_SYS_MEMBARRIER
static
-void rcu_sys_membarrier_status(int available)
+void rcu_sys_membarrier_status(bool available)
{
if (!available)
abort();
}
#else
static
-void rcu_sys_membarrier_status(int available)
+void rcu_sys_membarrier_status(bool available)
{
- if (available)
- rcu_has_sys_membarrier_memb = 1;
+ if (!available)
+ return;
+ urcu_memb_has_sys_membarrier = 1;
}
#endif
-void rcu_init(void)
+static
+void rcu_sys_membarrier_init(void)
{
- int ret;
+ bool available = false;
+ int mask;
+
+ mask = membarrier(MEMBARRIER_CMD_QUERY, 0);
+ if (mask >= 0) {
+ if (mask & MEMBARRIER_CMD_PRIVATE_EXPEDITED) {
+ if (membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0))
+ urcu_die(errno);
+ urcu_memb_has_sys_membarrier_private_expedited = 1;
+ available = true;
+ } else if (mask & MEMBARRIER_CMD_SHARED) {
+ available = true;
+ }
+ }
+ rcu_sys_membarrier_status(available);
+}
+void rcu_init(void)
+{
if (init_done)
return;
init_done = 1;
- ret = membarrier(MEMBARRIER_CMD_QUERY, 0);
- rcu_sys_membarrier_status(ret >= 0 && (ret & MEMBARRIER_CMD_SHARED));
+ rcu_sys_membarrier_init();
}
+URCU_ATTR_ALIAS(urcu_stringify(rcu_init))
+void alias_rcu_init(void);
#endif
#ifdef RCU_SIGNAL
if (ret)
urcu_die(errno);
}
+URCU_ATTR_ALIAS(urcu_stringify(rcu_init))
+void alias_rcu_init(void);
void rcu_exit(void)
{
* assert(cds_list_empty(®istry));
*/
}
+URCU_ATTR_ALIAS(urcu_stringify(rcu_exit))
+void alias_rcu_exit(void);
#endif /* #ifdef RCU_SIGNAL */
DEFINE_RCU_FLAVOR(rcu_flavor);
+DEFINE_RCU_FLAVOR_ALIAS(rcu_flavor, alias_rcu_flavor);
#include "urcu-call-rcu-impl.h"
#include "urcu-defer-impl.h"