aboutsummaryrefslogtreecommitdiffstats
path: root/createbarriergroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'createbarriergroup.c')
-rw-r--r--createbarriergroup.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/createbarriergroup.c b/createbarriergroup.c
new file mode 100644
index 0000000..694032b
--- /dev/null
+++ b/createbarriergroup.c
@@ -0,0 +1,59 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+#ifndef SINGLE_THREADED
+static void *
+slaveloop(void *thread_param)
+{
+ struct thread_data *data = thread_param;
+ void (*action)(struct algorithm *, struct global_data *);
+ size_t index;
+
+ for (;;) {
+ barrierwait(&data->group->barrier);
+ action = data->global->action;
+ if (!action)
+ break;
+ for (index = data->index; index < data->global->nalgorithms; index += data->group->nthreads + 1U)
+ (*action)(&data->global->algorithms[index], data->global);
+ barrierwait(&data->group->barrier);
+ }
+
+ return NULL;
+}
+#endif
+
+
+void
+createbarriergroup(struct barrier_group *group_out, size_t count, struct global_data *global)
+{
+#ifndef SINGLE_THREADED
+ size_t i;
+
+ count = MAX(count, 64);
+
+ group_out->nthreads = count - 1U;
+ group_out->threads = NULL;
+ if (!group_out->nthreads)
+ return;
+ group_out->threads = ecalloc(group_out->nthreads, sizeof(*group_out->threads));
+
+ if ((errno = pthread_barrier_init(&group_out->barrier, NULL, (unsigned)count)))
+ eprintf("pthread_barrier_init NULL %u:", (unsigned)count);
+
+ for (i = 0; i < group_out->nthreads; i++) {
+ group_out->threads[i].group = group_out;
+ group_out->threads[i].global = global;
+ group_out->threads[i].index = i + 1U;
+ errno = pthread_create(&group_out->threads[i].thread, NULL, &slaveloop, &group_out->threads[i]);
+ if (errno)
+ eprintf("pthread_create NULL:");
+ }
+#else
+ group_out->nthreads = 0U;
+ group_out->threads = NULL;
+ (void) global;
+ (void) count;
+#endif
+}