qsbr: portability fixes: use unsigned long for the gp counters.
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Thu, 17 Sep 2009 15:11:42 +0000 (11:11 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Thu, 17 Sep 2009 15:11:42 +0000 (11:11 -0400)
unsigned wraps properly in C (modulo ULONG_MAX + 1), IOW ULONG_MAX + 2
_is_ defined and is 1.

Rewrite rcu_gp_ongoing test to work in the unsigned case:

    a - b < 0

becomes

    a - b > ULONG_MAX / 2

This test actually means a - b > 0x7f....f which is exactly what we want
to test for in the first place, but in a portable way.

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 8d8aa3f8f60519620dbcfb78aef1b007c6183e5c..3d2ec8f3af5b046c9ca66c3b24e4e77aa762d358 100644 (file)
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #include <pthread.h>
 #include <assert.h>
+#include <limits.h>
 
 #include <compiler.h>
 #include <arch.h>
@@ -165,18 +166,18 @@ static inline void reader_barrier()
  * Using a int rather than a char to eliminate false register dependencies
  * causing stalls on some architectures.
  */
-extern long urcu_gp_ctr;
+extern unsigned long urcu_gp_ctr;
 
-extern long __thread rcu_reader_qs_gp;
+extern unsigned long __thread rcu_reader_qs_gp;
 
-static inline int rcu_gp_ongoing(long *value)
+static inline int rcu_gp_ongoing(unsigned long *value)
 {
-       long reader_gp;
+       unsigned long reader_gp;
 
        if (value == NULL)
                return 0;
        reader_gp = LOAD_SHARED(*value);
-       return reader_gp && (reader_gp - urcu_gp_ctr < 0);
+       return reader_gp && (reader_gp - urcu_gp_ctr > ULONG_MAX / 2);
 }
 
 static inline void _rcu_read_lock(void)
index 1955277ac65d309e8b187f82b2eec242a7d211f2..c0e643dab54f460b59e3646ade4af850fd9d05fb 100644 (file)
@@ -42,20 +42,20 @@ pthread_mutex_t urcu_mutex = PTHREAD_MUTEX_INITIALIZER;
 /*
  * Global grace period counter.
  */
-long urcu_gp_ctr = 1;
+unsigned long urcu_gp_ctr = 1;
 
 /*
  * Written to only by each individual reader. Read by both the reader and the
  * writers.
  */
-long __thread rcu_reader_qs_gp;
+unsigned long __thread rcu_reader_qs_gp;
 
 /* Thread IDs of registered readers */
 #define INIT_NUM_THREADS 4
 
 struct reader_registry {
        pthread_t tid;
-       long *rcu_reader_qs_gp;
+       unsigned long *rcu_reader_qs_gp;
 };
 
 #ifdef DEBUG_YIELD
@@ -139,7 +139,7 @@ static void wait_for_quiescent_state(void)
 
 void synchronize_rcu(void)
 {
-       long was_online;
+       unsigned long was_online;
 
        was_online = rcu_reader_qs_gp;
 
This page took 0.029485 seconds and 4 git commands to generate.