qsbr: micro optimization of the gp use.
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Thu, 17 Sep 2009 12:38:06 +0000 (08:38 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Thu, 17 Sep 2009 12:38:06 +0000 (08:38 -0400)
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>
urcu-qsbr-static.h
urcu-qsbr.c

index b18affeb1be6ea203b7636e5f235011cd01580b7..8d8aa3f8f60519620dbcfb78aef1b007c6183e5c 100644 (file)
@@ -176,7 +176,7 @@ static inline int rcu_gp_ongoing(long *value)
        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)
@@ -191,7 +191,7 @@ static inline void _rcu_read_unlock(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();
 }
 
@@ -203,7 +203,7 @@ static inline void _rcu_thread_offline(void)
 
 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();
 }
 
index 3f21be3160731979b6f39455b1202ccf00849237..1955277ac65d309e8b187f82b2eec242a7d211f2 100644 (file)
@@ -42,7 +42,7 @@ pthread_mutex_t urcu_mutex = PTHREAD_MUTEX_INITIALIZER;
 /*
  * 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
@@ -139,9 +139,9 @@ static void wait_for_quiescent_state(void)
 
 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
@@ -158,7 +158,7 @@ void synchronize_rcu(void)
        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();
 }
 
This page took 0.026707 seconds and 4 git commands to generate.