Port: no symbols aliases on MacOS
[urcu.git] / src / urcu.c
index a81b12913e92d86b8eea95203f8d9054de8dda52..c4e2dde9ab798986111ff070741b18c9e2cd237f 100644 (file)
 #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);
@@ -88,6 +103,8 @@ 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
@@ -112,13 +129,17 @@ static pthread_mutex_t rcu_gp_lock = PTHREAD_MUTEX_INITIALIZER;
  * 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(struct rcu_reader, rcu_reader);
+DEFINE_URCU_TLS(struct urcu_reader, rcu_reader);
+URCU_ATTR_ALIAS(urcu_stringify(rcu_reader))
+extern struct urcu_reader alias_rcu_reader;
 
 static CDS_LIST_HEAD(registry);
 
@@ -162,10 +183,14 @@ static void mutex_unlock(pthread_mutex_t *mutex)
 #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
 
@@ -179,7 +204,7 @@ static void smp_mb_master(void)
 #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
@@ -272,7 +297,7 @@ static void wait_for_readers(struct cds_list_head *input_readers,
                        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 */
@@ -292,18 +317,18 @@ static void wait_for_readers(struct cds_list_head *input_readers,
                }
 
                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
@@ -443,7 +468,7 @@ void synchronize_rcu(void)
        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
@@ -490,6 +515,8 @@ out:
         */
        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.
@@ -499,22 +526,28 @@ void rcu_read_lock(void)
 {
        _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);
@@ -523,6 +556,8 @@ void rcu_register_thread(void)
        cds_list_add(&URCU_TLS(rcu_reader).node, &registry);
        mutex_unlock(&rcu_registry_lock);
 }
+URCU_ATTR_ALIAS(urcu_stringify(rcu_register_thread))
+void alias_rcu_register_thread();
 
 void rcu_unregister_thread(void)
 {
@@ -532,35 +567,57 @@ 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
@@ -600,6 +657,8 @@ void rcu_init(void)
        if (ret)
                urcu_die(errno);
 }
+URCU_ATTR_ALIAS(urcu_stringify(rcu_init))
+void alias_rcu_init(void);
 
 void rcu_exit(void)
 {
@@ -612,10 +671,13 @@ void rcu_exit(void)
         * assert(cds_list_empty(&registry));
         */
 }
+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"
This page took 0.025846 seconds and 4 git commands to generate.