rculfstack: document "push"
[urcu.git] / urcu-qsbr.c
index 8dcad33e3d6297111b4967846af177ea8f0fc5f8..8d8a9cf05ced0fd18ef9943110dc22a2e6e05e87 100644 (file)
  * IBM's contributions to this file may be relicensed under LGPLv2 or later.
  */
 
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <pthread.h>
 #include <signal.h>
 #include <assert.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <string.h>
 #include <errno.h>
 #include <poll.h>
 
-#include "urcu-qsbr-map.h"
+#include "urcu/map/urcu-qsbr.h"
 
 #define BUILD_QSBR_LIB
-#include "urcu-qsbr-static.h"
+#include "urcu/static/urcu-qsbr.h"
 /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */
 #include "urcu-qsbr.h"
 
@@ -43,13 +45,18 @@ void __attribute__((destructor)) rcu_exit(void);
 
 static pthread_mutex_t rcu_gp_lock = PTHREAD_MUTEX_INITIALIZER;
 
-int gp_futex;
+int32_t gp_futex;
 
 /*
  * Global grace period counter.
  */
 unsigned long rcu_gp_ctr = RCU_GP_ONLINE;
 
+/*
+ * Active attempts to check for reader Q.S. before calling futex().
+ */
+#define RCU_QS_ACTIVE_ATTEMPTS 100
+
 /*
  * Written to only by each individual reader. Read by both the reader and the
  * writers.
@@ -143,26 +150,33 @@ static void update_counter_and_wait(void)
         */
        for (;;) {
                wait_loops++;
-               if (wait_loops == RCU_QS_ACTIVE_ATTEMPTS) {
-                       uatomic_dec(&gp_futex);
+               if (wait_loops >= RCU_QS_ACTIVE_ATTEMPTS) {
+                       uatomic_set(&gp_futex, -1);
+                       /*
+                        * Write futex before write waiting (the other side
+                        * reads them in the opposite order).
+                        */
+                       cmm_smp_wmb();
+                       cds_list_for_each_entry(index, &registry, node) {
+                               _CMM_STORE_SHARED(index->waiting, 1);
+                       }
                        /* Write futex before read reader_gp */
                        cmm_smp_mb();
                }
-
                cds_list_for_each_entry_safe(index, tmp, &registry, node) {
                        if (!rcu_gp_ongoing(&index->ctr))
                                cds_list_move(&index->node, &qsreaders);
                }
 
                if (cds_list_empty(&registry)) {
-                       if (wait_loops == RCU_QS_ACTIVE_ATTEMPTS) {
+                       if (wait_loops >= RCU_QS_ACTIVE_ATTEMPTS) {
                                /* Read reader_gp before write futex */
                                cmm_smp_mb();
                                uatomic_set(&gp_futex, 0);
                        }
                        break;
                } else {
-                       if (wait_loops == RCU_QS_ACTIVE_ATTEMPTS) {
+                       if (wait_loops >= RCU_QS_ACTIVE_ATTEMPTS) {
                                wait_gp();
                        } else {
 #ifndef HAS_INCOHERENT_CACHES
@@ -334,3 +348,4 @@ void rcu_exit(void)
 }
 
 #include "urcu-call-rcu-impl.h"
+#include "urcu-defer-impl.h"
This page took 0.0235 seconds and 4 git commands to generate.