From cca4c8dc770c0a5d6cdcd7375fd9d949ab5d7b99 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Sat, 1 Mar 2014 16:22:52 -0500 Subject: [PATCH] Fix: move wait loop increment before first conditional block 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 --- urcu-qsbr.c | 4 ++-- urcu.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/urcu-qsbr.c b/urcu-qsbr.c index 76aaabb..a2cabb4 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -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, ®istry, node) { if (!rcu_gp_ongoing(&index->ctr)) diff --git a/urcu.c b/urcu.c index 33e35e1..8420ee4 100644 --- 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, ®istry, node) { -- 2.34.1