Follow-up on 1a80f3: since now `0' for a gp counter means "offline", just
be sure that the global GP counter is never zero. To achieve that, let its
first value ever be one, and increment it 2 by 2 like previously done.
Note that it internaly uses the fact that signed integers wraps (which the
previous code already assumed anyways) but this is undefined behaviour in
C. Using unsigned longs would probably be more portable.
This way, setting the cpu online, marking a quiescent state is just a
matter of copying the global gp counter instead of incrementing it by one.
This saves one CPU instruction, and supposedly even register use for
architectures providing memory to memory copy operands.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
if (value == NULL)
return 0;
reader_gp = LOAD_SHARED(*value);
- return (reader_gp & 1) && (reader_gp - urcu_gp_ctr < 0);
+ return reader_gp && (reader_gp - urcu_gp_ctr < 0);
}
static inline void _rcu_read_lock(void)
static inline void _rcu_quiescent_state(void)
{
smp_mb();
- _STORE_SHARED(rcu_reader_qs_gp, _LOAD_SHARED(urcu_gp_ctr) + 1);
+ _STORE_SHARED(rcu_reader_qs_gp, _LOAD_SHARED(urcu_gp_ctr));
smp_mb();
}
static inline void _rcu_thread_online(void)
{
- _STORE_SHARED(rcu_reader_qs_gp, LOAD_SHARED(urcu_gp_ctr) + 1);
+ _STORE_SHARED(rcu_reader_qs_gp, LOAD_SHARED(urcu_gp_ctr));
smp_mb();
}
/*
* Global grace period counter.
*/
-long urcu_gp_ctr = 0;
+long urcu_gp_ctr = 1;
/*
* Written to only by each individual reader. Read by both the reader and the
void synchronize_rcu(void)
{
- int was_online;
+ long was_online;
- was_online = rcu_reader_qs_gp & 1;
+ was_online = rcu_reader_qs_gp;
/*
* Mark the writer thread offline to make sure we don't wait for
internal_urcu_unlock();
if (was_online)
- _STORE_SHARED(rcu_reader_qs_gp, LOAD_SHARED(urcu_gp_ctr) + 1);
+ _STORE_SHARED(rcu_reader_qs_gp, LOAD_SHARED(urcu_gp_ctr));
smp_mb();
}