qsbr: Use adaptative wait delay
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Sat, 26 Sep 2009 20:01:53 +0000 (16:01 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Sat, 26 Sep 2009 20:01:53 +0000 (16:01 -0400)
Use a wait delay based on the last Q.S. duration of the thread we are waiting
for.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
urcu-qsbr-static.h
urcu-qsbr.c

index 9cc5db493ca1362d1781b44507a10e562623df1f..d18fabd3cb55f1c6cedec6c78bd1753d7348add0 100644 (file)
@@ -34,6 +34,7 @@
 #include <assert.h>
 #include <limits.h>
 #include <sched.h>
+#include <sys/time.h>
 
 #include <compiler.h>
 #include <arch.h>
@@ -181,6 +182,8 @@ extern unsigned long urcu_gp_ctr;
 struct urcu_reader_status {
        unsigned long qs_gp;
        unsigned long gp_waiting;
+       unsigned long qs_time_delta_usec;
+       struct timeval qs_time_last;
 };
 
 extern struct urcu_reader_status __thread urcu_reader_status;
@@ -219,8 +222,17 @@ static inline void _rcu_read_unlock(void)
 static inline void _rcu_quiescent_state(void)
 {
        long gp_ctr;
+       struct timeval current_time;
 
        smp_mb();
+       gettimeofday(&current_time, NULL);
+       if (current_time.tv_sec - urcu_reader_status.qs_time_last.tv_sec >= 1)
+               _STORE_SHARED(urcu_reader_status.qs_time_delta_usec, 1000000);
+       else
+               _STORE_SHARED(urcu_reader_status.qs_time_delta_usec,
+                     (unsigned long)current_time.tv_usec
+                     - (unsigned long)urcu_reader_status.qs_time_last.tv_usec);
+       urcu_reader_status.qs_time_last = current_time;
        /*
         * volatile accesses can be reordered by the compiler when put in the
         * same expression.
@@ -247,6 +259,17 @@ static inline void _rcu_thread_offline(void)
 
 static inline void _rcu_thread_online(void)
 {
+       struct timeval current_time;
+
+       gettimeofday(&current_time, NULL);
+       if (current_time.tv_sec - urcu_reader_status.qs_time_last.tv_sec >= 1)
+               _STORE_SHARED(urcu_reader_status.qs_time_delta_usec, 1000000);
+       else
+               _STORE_SHARED(urcu_reader_status.qs_time_delta_usec,
+                     (unsigned long)current_time.tv_usec
+                     - (unsigned long)urcu_reader_status.qs_time_last.tv_usec);
+       urcu_reader_status.qs_time_last = current_time;
+       _STORE_SHARED(urcu_reader_status.qs_time_delta_usec, 0);
        _STORE_SHARED(urcu_reader_status.qs_gp, LOAD_SHARED(urcu_gp_ctr));
        smp_mb();
 }
index c275b6670672de62fc76aed22ba432d6deea2b44..5f06bfaf523715e39c3625a3378666c87a012491 100644 (file)
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <errno.h>
 #include <poll.h>
+#include <unistd.h>
 
 #define BUILD_QSBR_LIB
 #include "urcu-qsbr-static.h"
@@ -117,7 +118,8 @@ static void wait_for_quiescent_state(void)
                index->urcu_reader_status->gp_waiting = 1;
                while (rcu_gp_ongoing(&index->urcu_reader_status->qs_gp)) {
                        if (wait_loops++ == RCU_QS_ACTIVE_ATTEMPTS) {
-                               sched_yield();  /* ideally sched_yield_to() */
+                               /* adapted wait time, in us */
+                               usleep(LOAD_SHARED(index->urcu_reader_status->qs_time_delta_usec));
                                wait_loops = 0;
                        } else {
 #ifndef HAS_INCOHERENT_CACHES
This page took 0.026333 seconds and 4 git commands to generate.