Public
Snippet $181 authored by Kirill Smelkov

benchmark: create threads -> do ø work -> join

Edited
Tthread.c
// benchmark: create threads -> do ø work -> join
#include <stdint.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>

#define	N 10000LL
//         123456789


struct WaitGroup {
	uint64_t value;
	sem_t	 sem;
};

void WaitGroup_Init(struct WaitGroup *wg) {
	int err;

	wg->value = 0;
	err = sem_init(&wg->sem, /*pshared=*/0, 0);
	if (err) {
		perror("sem_init");
		abort();
	}
}

void WaitGroup_Add(struct WaitGroup *wg, uint64_t value) {
	uint64_t v;
	v = __sync_add_and_fetch(&wg->value, value);

	// wake-up waiter
	if (v == 0) {
		int err;
		err = sem_post(&wg->sem);
		if (err) {
			perror("sem_post");
			abort();
		}
	}
}

void WaitGroup_Done(struct WaitGroup *wg) {
	WaitGroup_Add(wg, -1ULL);
}

void WaitGroup_Wait(struct WaitGroup *wg) {
	int err;

	err = sem_wait(&wg->sem);
	if (err) {
		perror("sem_wait");
		abort();
	}
}

void *nothing(void *arg) {
	struct WaitGroup *wg = arg;
	//fprintf(stderr, ".\n");
	WaitGroup_Done(wg);
	return NULL;
}

int main() {
	int64_t i;
	pthread_t T;
	struct WaitGroup wg;
	int err;

	WaitGroup_Init(&wg);

	for (i = 0; i < N; i++) {
		WaitGroup_Add(&wg, 1);
		err = pthread_create(&T, NULL, nothing, &wg);
		if (err) {
			perror("thread create:");
			abort();
		}
	}

	WaitGroup_Wait(&wg);
	return 0;
}