Fix: move wait loop increment before first conditional block
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 1 Mar 2014 21:22:52 +0000 (16:22 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 1 Mar 2014 21:32:51 +0000 (16:32 -0500)
The fix "Fix: high cpu usage in synchronize_rcu with long RCU read-side
C.S." has an imperfection in urcu.c and urcu-qsbr.c: when incrementing
the wait loop counter for the last time, the first conditional branch is
not taken, but the following conditionals are, and they assume the first
conditional has been taken.

Within urcu.c (urcu-mb, urcu-membarrier and urcu-signal), and
urcu-qsbr.c, this will simply skip the first wait_gp() call, without any
noticeable ill side-effect.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
urcu-qsbr.c
urcu.c

index 76aaabb4eac85fbb11aefc487bab627aa241a384..a2cabb446afda2db312b6d42a00b8ea5f02a4769 100644 (file)
@@ -150,6 +150,8 @@ static void update_counter_and_wait(void)
         * Wait for each thread rcu_reader_qs_gp count to become 0.
         */
        for (;;) {
+               if (wait_loops < RCU_QS_ACTIVE_ATTEMPTS)
+                       wait_loops++;
                if (wait_loops >= RCU_QS_ACTIVE_ATTEMPTS) {
                        uatomic_set(&gp_futex, -1);
                        /*
@@ -162,8 +164,6 @@ static void update_counter_and_wait(void)
                        }
                        /* Write futex before read reader_gp */
                        cmm_smp_mb();
-               } else {
-                       wait_loops++;
                }
                cds_list_for_each_entry_safe(index, tmp, &registry, node) {
                        if (!rcu_gp_ongoing(&index->ctr))
diff --git a/urcu.c b/urcu.c
index 33e35e1d36a722cb2de2f74e8f3a15c8327f3687..8420ee494cef759bc2b87287168bacddc525315c 100644 (file)
--- a/urcu.c
+++ b/urcu.c
@@ -247,12 +247,12 @@ void update_counter_and_wait(void)
         * Wait for each thread URCU_TLS(rcu_reader).ctr count to become 0.
         */
        for (;;) {
+               if (wait_loops < RCU_QS_ACTIVE_ATTEMPTS)
+                       wait_loops++;
                if (wait_loops >= RCU_QS_ACTIVE_ATTEMPTS) {
                        uatomic_dec(&gp_futex);
                        /* Write futex before read reader_gp */
                        smp_mb_master(RCU_MB_GROUP);
-               } else {
-                       wait_loops++;
                }
 
                cds_list_for_each_entry_safe(index, tmp, &registry, node) {
This page took 0.026028 seconds and 4 git commands to generate.