static inline int rcu_gp_ongoing(long *value)
{
+ long reader_gp;
+
if (value == NULL)
return 0;
-
- return LOAD_SHARED(*value) & 1;
+ reader_gp = LOAD_SHARED(*value);
+ return (reader_gp & 1) && (reader_gp - urcu_gp_ctr < 0);
}
static inline void _rcu_read_lock(void)
static inline void _rcu_quiescent_state(void)
{
smp_mb();
- rcu_reader_qs_gp = ACCESS_ONCE(urcu_gp_ctr) + 1;
+ _STORE_SHARED(rcu_reader_qs_gp, _LOAD_SHARED(urcu_gp_ctr) + 1);
smp_mb();
}
static inline void _rcu_thread_offline(void)
{
smp_mb();
- rcu_reader_qs_gp = 0;
+ STORE_SHARED(rcu_reader_qs_gp, 0);
}
static inline void _rcu_thread_online(void)
{
- rcu_reader_qs_gp = ACCESS_ONCE(urcu_gp_ctr) + 1;
+ _STORE_SHARED(rcu_reader_qs_gp, LOAD_SHARED(urcu_gp_ctr) + 1);
smp_mb();
}
*/
for (index = registry; index < registry + num_readers; index++) {
#ifndef HAS_INCOHERENT_CACHES
- while (rcu_gp_ongoing(index->rcu_reader_qs_gp) &&
- (*index->rcu_reader_qs_gp - urcu_gp_ctr < 0))
+ while (rcu_gp_ongoing(index->rcu_reader_qs_gp))
cpu_relax();
#else /* #ifndef HAS_INCOHERENT_CACHES */
int wait_loops = 0;
* BUSY-LOOP. Force the reader thread to commit its
* rcu_reader_qs_gp update to memory if we wait for too long.
*/
- while (rcu_gp_ongoing(index->rcu_reader_qs_gp) &&
- (*index->rcu_reader_qs_gp - urcu_gp_ctr < 0)) {
+ while (rcu_gp_ongoing(index->rcu_reader_qs_gp)) {
if (wait_loops++ == KICK_READER_LOOPS) {
force_mb_single_thread(index);
wait_loops = 0;
internal_urcu_lock();
force_mb_all_threads();
- urcu_gp_ctr += 2;
+ STORE_SHARED(urcu_gp_ctr, urcu_gp_ctr + 2);
wait_for_quiescent_state();
force_mb_all_threads();
internal_urcu_unlock();