aboutsummaryrefslogtreecommitdiff
path: root/src/threading.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/threading.cpp')
-rw-r--r--src/threading.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/threading.cpp b/src/threading.cpp
index fd6ebf9ad..61f9df2db 100644
--- a/src/threading.cpp
+++ b/src/threading.cpp
@@ -231,6 +231,46 @@ void yield_process(void);
}
#endif
+
+
+struct Barrier {
+ BlockingMutex mutex;
+ Condition cond;
+ isize index;
+ isize generation_id;
+ isize thread_count;
+};
+
+void barrier_init(Barrier *b, isize thread_count) {
+ mutex_init(&b->mutex);
+ condition_init(&b->cond);
+ b->index = 0;
+ b->generation_id = 0;
+ b->thread_count = 0;
+}
+
+void barrier_destroy(Barrier *b) {
+ condition_destroy(&b->cond);
+ mutex_destroy(&b->mutex);
+}
+
+// Returns true if it is the leader
+bool barrier_wait(Barrier *b) {
+ mutex_lock(&b->mutex);
+ defer (mutex_unlock(&b->mutex));
+ isize local_gen = b->generation_id;
+ b->index += 1;
+ if (b->index < b->thread_count) {
+ while (local_gen == b->generation_id && b->index < b->thread_count) {
+ condition_wait(&b->cond, &b->mutex);
+ }
+ return false;
+ }
+ b->index = 0;
+ b->generation_id += 1;
+ condition_broadcast(&b->cond);
+ return true;
+}