#include <errno.h>
#include <poll.h>
+#define BUILD_QSBR_LIB
#include "urcu-qsbr-static.h"
/* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */
#include "urcu-qsbr.h"
*/
for (index = registry; index < registry + num_readers; index++) {
#ifndef HAS_INCOHERENT_CACHES
- while (rcu_gp_ongoing(index->rcu_reader_qs_gp) &&
- (*index->rcu_reader_qs_gp - urcu_gp_ctr < 0))
+ while (rcu_gp_ongoing(index->rcu_reader_qs_gp))
cpu_relax();
#else /* #ifndef HAS_INCOHERENT_CACHES */
int wait_loops = 0;
* BUSY-LOOP. Force the reader thread to commit its
* rcu_reader_qs_gp update to memory if we wait for too long.
*/
- while (rcu_gp_ongoing(index->rcu_reader_qs_gp) &&
- (*index->rcu_reader_qs_gp - urcu_gp_ctr < 0)) {
+ while (rcu_gp_ongoing(index->rcu_reader_qs_gp)) {
if (wait_loops++ == KICK_READER_LOOPS) {
force_mb_single_thread(index);
wait_loops = 0;
void synchronize_rcu(void)
{
- internal_urcu_lock();
+ int was_online;
+
+ was_online = rcu_reader_qs_gp & 1;
+
+ /*
+ * 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)
+ _rcu_thread_offline();
+
force_mb_all_threads();
- urcu_gp_ctr += 2;
+ internal_urcu_lock();
+ STORE_SHARED(urcu_gp_ctr, urcu_gp_ctr + 2);
wait_for_quiescent_state();
- force_mb_all_threads();
internal_urcu_unlock();
+ force_mb_all_threads();
+
+ if (was_online)
+ _rcu_thread_online();
}
/*