X-Git-Url: https://git.lttng.org/?p=urcu.git;a=blobdiff_plain;f=urcu-qsbr.c;h=3b9a054b40b1bc61f29768bf5d4085d62a8b7bd9;hp=a86f6e94d5ae13eb24e5d34610a3d9c5954373b4;hb=bc49c323c92d6809e534fd0bb78309922c1cd2bb;hpb=47d2f29ead2c92123069ebf7b84c6e48cf91612a diff --git a/urcu-qsbr.c b/urcu-qsbr.c index a86f6e9..3b9a054 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -135,12 +135,24 @@ static void switch_next_urcu_qparity(void) void synchronize_rcu(void) { + unsigned long was_online; + + was_online = rcu_reader_qs_gp; + /* All threads should read qparity before accessing data structure * where new ptr points to. */ /* Write new ptr before changing the qparity */ smp_mb(); + /* + * Mark the writer thread offline to make sure we don't wait for + * our own quiescent state. This allows using synchronize_rcu() in + * threads registered as readers. + */ + if (was_online) + STORE_SHARED(rcu_reader_qs_gp, 0); + internal_urcu_lock(); switch_next_urcu_qparity(); /* 0 -> 1 */ @@ -183,9 +195,12 @@ void synchronize_rcu(void) internal_urcu_unlock(); - /* Finish waiting for reader threads before letting the old ptr being + /* + * Finish waiting for reader threads before letting the old ptr being * freed. */ + if (was_online) + _STORE_SHARED(rcu_reader_qs_gp, LOAD_SHARED(urcu_gp_ctr)); smp_mb(); } #else /* !(BITS_PER_LONG < 64) */