wingo pushed a commit to branch wip-whippet
in repository guile.

commit e4342f6c4586cda8639f49dd07cb02c1c7bae15e
Author: Andy Wingo <wi...@igalia.com>
AuthorDate: Mon Jun 6 16:57:22 2022 +0200

    Add helper for yielding in a spinlock
---
 parallel-tracer.h | 14 +++-----------
 spin.h            | 18 ++++++++++++++++++
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/parallel-tracer.h b/parallel-tracer.h
index 297e2dde8..02f641352 100644
--- a/parallel-tracer.h
+++ b/parallel-tracer.h
@@ -9,6 +9,7 @@
 #include "assert.h"
 #include "debug.h"
 #include "inline.h"
+#include "spin.h"
 
 // The Chase-Lev work-stealing deque, as initially described in "Dynamic
 // Circular Work-Stealing Deque" (Chase and Lev, SPAA'05)
@@ -530,8 +531,7 @@ trace_worker_check_termination(struct trace_worker *worker,
     return 1;
   }
 
-  size_t spin_count = 0;
-  while (1) {
+  for (size_t spin_count = 0;; spin_count++) {
     if (trace_worker_can_steal_from_any(worker, tracer)) {
       atomic_fetch_add_explicit(&tracer->active_tracers, 1,
                                 memory_order_relaxed);
@@ -544,15 +544,7 @@ trace_worker_check_termination(struct trace_worker *worker,
     }
     // spin
     DEBUG("tracer #%zu: spinning #%zu\n", worker->id, spin_count);
-    if (spin_count < 10)
-      __builtin_ia32_pause();
-    else if (spin_count < 20)
-      sched_yield();
-    else if (spin_count < 40)
-      usleep(0);
-    else
-      usleep(1);
-    spin_count++;
+    yield_for_spin(spin_count);
   }
 }
 
diff --git a/spin.h b/spin.h
new file mode 100644
index 000000000..d650c3216
--- /dev/null
+++ b/spin.h
@@ -0,0 +1,18 @@
+#ifndef SPIN_H
+#define SPIN_H
+
+#include <sched.h>
+#include <unistd.h>
+
+static inline void yield_for_spin(size_t spin_count) {
+  if (spin_count < 10)
+    __builtin_ia32_pause();
+  else if (spin_count < 20)
+    sched_yield();
+  else if (spin_count < 40)
+    usleep(0);
+  else
+    usleep(1);
+}  
+
+#endif // SPIN_H

Reply via email to