commit 37684c738d6677744ccc7db1b996c3f582c18b14
parent 24dc1c3d7d56994467f93d6d9bda162f5ea3366c
Author: Henry Wilson <henry@henryandlizzy.uk>
Date: Fri, 22 Sep 2023 21:33:37 +0100
barrier: Add example std::barrier thread synchronisation
Diffstat:
1 file changed, 51 insertions(+), 0 deletions(-)
diff --git a/src/barrier.cpp b/src/barrier.cpp
@@ -0,0 +1,51 @@
+#include <barrier>
+#include <iostream>
+#include <span>
+#include <syncstream>
+#include <thread>
+#include <utility>
+
+static unsigned phase;
+
+void barrier_cb()
+{
+ std::osyncstream{std::cout} << "Barrier: phase " << ++phase << "\n";
+}
+
+void work(unsigned i, std::barrier<void(*)()>* b)
+{
+ unsigned name = i;
+
+ while (i)
+ {
+ b->arrive_and_wait();
+ std::osyncstream{std::cout} << name << ": doing phase " << phase << " work: " << i-- << "\n";
+ }
+ b->arrive_and_drop();
+}
+
+void do_works(std::span<unsigned> eyes)
+{
+ phase = 0;
+ if (eyes.empty())
+ return;
+
+ if (std::cmp_greater(eyes.size(), std::barrier<void(*)()>::max()))
+ std::terminate();
+
+ auto n = static_cast<ptrdiff_t>(eyes.size());
+ auto thread_eyes = eyes.subspan(0, n - 1);
+ std::barrier b{n, barrier_cb};
+ std::jthread thrds[thread_eyes.size()], *t = thrds;
+
+ for (auto i : thread_eyes)
+ *t++ = std::jthread(work, i , &b);
+
+ work(eyes.back(), &b);
+}
+
+int main()
+{
+ unsigned x[] = {1,2,4,3};
+ do_works(x);
+}