Port: Fixes to build system for portability
[urcu.git] / urcu-call-rcu-impl.h
index f02405ddd698ca684901a3d68c2534b9e9295b9e..d33c731ad1e9eae6437ae95595ecf0c825f3e6e8 100644 (file)
@@ -256,9 +256,22 @@ static void call_rcu_wait(struct call_rcu_data *crdp)
 {
        /* Read call_rcu list before read futex */
        cmm_smp_mb();
-       if (uatomic_read(&crdp->futex) == -1)
-               futex_async(&crdp->futex, FUTEX_WAIT, -1,
-                     NULL, NULL, 0);
+       if (uatomic_read(&crdp->futex) != -1)
+               return;
+       while (futex_async(&crdp->futex, FUTEX_WAIT, -1,
+                       NULL, NULL, 0)) {
+               switch (errno) {
+               case EWOULDBLOCK:
+                       /* Value already changed. */
+                       return;
+               case EINTR:
+                       /* Retry if interrupted by signal. */
+                       break;  /* Get out of switch. */
+               default:
+                       /* Unexpected error. */
+                       urcu_die(errno);
+               }
+       }
 }
 
 static void call_rcu_wake_up(struct call_rcu_data *crdp)
@@ -267,8 +280,9 @@ static void call_rcu_wake_up(struct call_rcu_data *crdp)
        cmm_smp_mb();
        if (caa_unlikely(uatomic_read(&crdp->futex) == -1)) {
                uatomic_set(&crdp->futex, 0);
-               futex_async(&crdp->futex, FUTEX_WAKE, 1,
-                     NULL, NULL, 0);
+               if (futex_async(&crdp->futex, FUTEX_WAKE, 1,
+                               NULL, NULL, 0) < 0)
+                       urcu_die(errno);
        }
 }
 
@@ -276,9 +290,22 @@ static void call_rcu_completion_wait(struct call_rcu_completion *completion)
 {
        /* Read completion barrier count before read futex */
        cmm_smp_mb();
-       if (uatomic_read(&completion->futex) == -1)
-               futex_async(&completion->futex, FUTEX_WAIT, -1,
-                     NULL, NULL, 0);
+       if (uatomic_read(&completion->futex) != -1)
+               return;
+       while (futex_async(&completion->futex, FUTEX_WAIT, -1,
+                       NULL, NULL, 0)) {
+               switch (errno) {
+               case EWOULDBLOCK:
+                       /* Value already changed. */
+                       return;
+               case EINTR:
+                       /* Retry if interrupted by signal. */
+                       break;  /* Get out of switch. */
+               default:
+                       /* Unexpected error. */
+                       urcu_die(errno);
+               }
+       }
 }
 
 static void call_rcu_completion_wake_up(struct call_rcu_completion *completion)
@@ -287,8 +314,9 @@ static void call_rcu_completion_wake_up(struct call_rcu_completion *completion)
        cmm_smp_mb();
        if (caa_unlikely(uatomic_read(&completion->futex) == -1)) {
                uatomic_set(&completion->futex, 0);
-               futex_async(&completion->futex, FUTEX_WAKE, 1,
-                     NULL, NULL, 0);
+               if (futex_async(&completion->futex, FUTEX_WAKE, 1,
+                               NULL, NULL, 0) < 0)
+                       urcu_die(errno);
        }
 }
 
This page took 0.024716 seconds and 4 git commands to generate.