+ long v;
+
+ if (value == NULL)
+ return 0;
+ /*
+ * Make sure both tests below are done on the same version of *value
+ * to insure consistency.
+ */
+ v = LOAD_SHARED(*value);
+ return (v & RCU_GP_CTR_NEST_MASK) &&
+ ((v ^ urcu_gp_ctr) & RCU_GP_CTR_BIT);
+}
+
+static inline void rcu_read_lock(void)
+{
+ long tmp;
+
+ tmp = urcu_active_readers;
+ /* urcu_gp_ctr = RCU_GP_COUNT | (~RCU_GP_CTR_BIT or RCU_GP_CTR_BIT) */
+ /*
+ * The data dependency "read urcu_gp_ctr, write urcu_active_readers",
+ * serializes those two memory operations. The memory barrier in the
+ * signal handler ensures we receive the proper memory commit barriers
+ * required by _STORE_SHARED and _LOAD_SHARED whenever communication
+ * with the writer is needed.
+ */
+ if (likely(!(tmp & RCU_GP_CTR_NEST_MASK)))
+ _STORE_SHARED(urcu_active_readers, _LOAD_SHARED(urcu_gp_ctr));
+ else
+ _STORE_SHARED(urcu_active_readers, tmp + RCU_GP_COUNT);