aboutsummaryrefslogblamecommitdiffstats
path: root/createbarriergroup.c
blob: 694032b46a67464bdca9ddc2d28cf345e40fd7dc (plain) (tree)


























































                                                                                                                 
/* 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
}