Fix qsbr urcu implementation
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Wed, 10 Jun 2009 15:55:06 +0000 (11:55 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Wed, 10 Jun 2009 15:55:06 +0000 (11:55 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
urcu-qsbr.c
urcu-qsbr.h

index 48bc62ec25e09e18395970d591f9dc64b57a1ed7..6ba03642f852763057781dcf14bf2ff4a01dc5b9 100644 (file)
@@ -32,9 +32,9 @@
 #include <errno.h>
 #include <poll.h>
 
-#include "urcu-static.h"
+#include "urcu-qsbr.h"
 /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */
-#include "urcu.h"
+//#include "urcu.h"
 
 pthread_mutex_t urcu_mutex = PTHREAD_MUTEX_INITIALIZER;
 
@@ -47,14 +47,14 @@ long urcu_gp_ctr = 0;
  * Written to only by each individual reader. Read by both the reader and the
  * writers.
  */
-long __thread urcu_active_readers;
+long __thread rcu_reader_qs_gp;
 
 /* Thread IDs of registered readers */
 #define INIT_NUM_THREADS 4
 
 struct reader_registry {
        pthread_t tid;
-       long *urcu_active_readers;
+       long *rcu_reader_qs_gp;
        char *need_mb;
 };
 
@@ -124,19 +124,21 @@ void wait_for_quiescent_state(void)
        if (!registry)
                return;
        /*
-        * Wait for each thread urcu_active_readers count to become 0.
+        * Wait for each thread rcu_reader_qs_gp count to become 0.
         */
        for (index = registry; index < registry + num_readers; index++) {
 #ifndef HAS_INCOHERENT_CACHES
-               while (rcu_old_gp_ongoing(index->urcu_active_readers))
+               while (rcu_gp_ongoing(index->rcu_reader_qs_gp) &&
+                      (*index->rcu_reader_qs_gp - urcu_gp_ctr < 0))
                        cpu_relax();
 #else /* #ifndef HAS_INCOHERENT_CACHES */
                int wait_loops = 0;
                /*
                 * BUSY-LOOP. Force the reader thread to commit its
-                * urcu_active_readers update to memory if we wait for too long.
+                * rcu_reader_qs_gp update to memory if we wait for too long.
                 */
-               while (rcu_old_gp_ongoing(index->urcu_active_readers)) {
+               while (rcu_gp_ongoing(index->rcu_reader_qs_gp) &&
+                      (*index->rcu_reader_qs_gp - urcu_gp_ctr < 0)) {
                        if (wait_loops++ == KICK_READER_LOOPS) {
                                force_mb_single_thread(index);
                                wait_loops = 0;
@@ -219,7 +221,7 @@ static void rcu_add_reader(pthread_t id)
        }
        registry[num_readers].tid = id;
        /* reference to the TLS of _this_ reader thread. */
-       registry[num_readers].urcu_active_readers = &urcu_active_readers;
+       registry[num_readers].rcu_reader_qs_gp = &rcu_reader_qs_gp;
        registry[num_readers].need_mb = &need_mb;
        num_readers++;
 }
@@ -238,7 +240,7 @@ static void rcu_remove_reader(pthread_t id)
                        memcpy(index, &registry[num_readers - 1],
                                sizeof(struct reader_registry));
                        registry[num_readers - 1].tid = 0;
-                       registry[num_readers - 1].urcu_active_readers = NULL;
+                       registry[num_readers - 1].rcu_reader_qs_gp = NULL;
                        num_readers--;
                        return;
                }
index 59621807abf470012bc94ee48cc7e6ee786d2b65..f5392a32dfcc7ae3a4647b4a12f4882baaf042bc 100644 (file)
 
 /*
  * If a reader is really non-cooperative and refuses to commit its
- * urcu_active_readers count to memory (there is no barrier in the reader
+ * rcu_reader_qs_gp count to memory (there is no barrier in the reader
  * per-se), kick it after a few loops waiting for it.
  */
 #define KICK_READER_LOOPS 10000
@@ -161,15 +161,6 @@ static inline void reader_barrier()
        smp_mb();
 }
 
-/*
- * The trick here is that RCU_GP_CTR_BIT must be a multiple of 8 so we can use a
- * full 8-bits, 16-bits or 32-bits bitmask for the lower order bits.
- */
-#define RCU_GP_COUNT           (1UL << 0)
-/* Use the amount of bits equal to half of the architecture long size */
-#define RCU_GP_CTR_BIT         (1UL << (sizeof(long) << 2))
-#define RCU_GP_CTR_NEST_MASK   (RCU_GP_CTR_BIT - 1)
-
 /*
  * Global quiescent period counter with low-order bits unused.
  * Using a int rather than a char to eliminate false register dependencies
@@ -177,9 +168,9 @@ static inline void reader_barrier()
  */
 extern long urcu_gp_ctr;
 
-extern long __thread urcu_active_readers;
+extern long __thread rcu_reader_qs_gp;
 
-static inline int rcu_old_gp_ongoing(long *value)
+static inline int rcu_gp_ongoing(long *value)
 {
        if (value == NULL)
                return 0;
@@ -198,19 +189,19 @@ static inline void _rcu_read_unlock(void)
 static inline void _rcu_quiescent_state(void)
 {
        smp_mb();       
-       urcu_active_readers = ACCESS_ONCE(urcu_gp_ctr) + 1;
+       rcu_reader_qs_gp = ACCESS_ONCE(urcu_gp_ctr) + 1;
        smp_mb();
 }
 
 static inline void _rcu_thread_offline(void)
 {
        smp_mb();
-       urcu_active_readers = ACCESS_ONCE(urcu_gp_ctr);
+       rcu_reader_qs_gp = ACCESS_ONCE(urcu_gp_ctr);
 }
 
 static inline void _rcu_thread_online(void)
 {
-       urcu_active_readers = ACCESS_ONCE(urcu_gp_ctr) + 1;
+       rcu_reader_qs_gp = ACCESS_ONCE(urcu_gp_ctr) + 1;
        smp_mb();
 }
 
This page took 0.02793 seconds and 4 git commands to generate.