From 608f4f254ccf95a01b5480e2dbe7a1b6e54c8609 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Fri, 8 Apr 2016 16:39:03 -0400 Subject: sitting here --- wg.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 wg.c (limited to 'wg.c') diff --git a/wg.c b/wg.c new file mode 100644 index 0000000..4f60765 --- /dev/null +++ b/wg.c @@ -0,0 +1,45 @@ +#include +#include +#include /* for EXIT_FAILURE */ +#include + +#include "wg.h" + +/* Thread management tools modeled on https://golang.org/pkg/sync/#WaitGroup */ + +/* pthread_cond_t is overly complicated. Just use a self-pipe. */ + +void wg_init(struct wg *wg) { + wg->count = 0; + pthread_mutex_init(&wg->lock, NULL); + int fds[2]; + if (pipe(fds) != 0) + error(EXIT_FAILURE, errno, "pipe"); + wg->fd_wait = fds[0]; + wg->fd_signal = fds[1]; +} + +void wg_add(struct wg *wg, unsigned int n) { + pthread_mutex_lock(&wg->lock); + wg->count += n; + pthread_mutex_unlock(&wg->lock); +} + +void wg_sub(struct wg *wg, unsigned int n) { + pthread_mutex_lock(&wg->lock); + wg->count -= n; + if (wg->count == 0) + if (write(wg->fd_signal, " ", 1) < 1) + error(EXIT_FAILURE, errno, "write"); + pthread_mutex_unlock(&wg->lock); +} + +void wg_wait(struct wg *wg) { + char b; + retry: + if (read(wg->fd_wait, &b, 1) == -1) { + if (errno == EINTR) + goto retry; + error(EXIT_FAILURE, errno, "wg_wait"); + } +} -- cgit v1.2.3-54-g00ecf