c-template
wait_group.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdatomic.h>
4 #include <pthread.h>
5 #include <unistd.h>
6 #include <assert.h>
7 #include "../../include/sync/wait_group.h"
8 
10  wait_group_t *wg = malloc(sizeof(wait_group_t));
11  if (wg == NULL) {
12  return NULL;
13  }
14  wg->active_processes = 0;
15  pthread_mutex_init(&wg->mutex, NULL);
16  pthread_mutex_init(&wg->cond_mutex, NULL);
17  pthread_cond_init(&wg->cond_var, NULL);
18  return wg;
19 }
20 
22  pthread_mutex_lock(&wg->cond_mutex);
23  pthread_cond_wait(&wg->cond_var, &wg->cond_mutex);
24  pthread_mutex_lock(&wg->cond_mutex);
25 }
26 
28  pthread_mutex_lock(&wg->cond_mutex);
29  pthread_cond_signal(&wg->cond_var);
30  pthread_mutex_unlock(&wg->cond_mutex);
31 }
32 
34  // signal anyone waiting on the current cond_var
35  // we do this before replacing it
36  pthread_mutex_lock(&wg->cond_mutex);
37  pthread_cond_signal(&wg->cond_var);
38  pthread_mutex_unlock(&wg->cond_mutex);
39  // re init
40  pthread_mutex_lock(&wg->cond_mutex);
41  pthread_cond_init(&wg->cond_var, NULL);
42  pthread_mutex_unlock(&wg->cond_mutex);
43 }
44 
46  for (;;) {
47  // sleep for 750 milisecond
48  sleep(0.75);
49  // NOTE(bonedaddy): iirc we dont need this
50  // pthread_mutex_lock(&wg->mutex);
51  int count = wg->active_processes;
52  // NOTE(bonedaddy): iirc we dont need this
53  // pthread_mutex_unlock(&wg->mutex);
54  if (count == 0) {
55  break;
56  }
57  }
58  // lock before destroy
59  pthread_mutex_lock(&wg->mutex);
60  pthread_mutex_destroy(&wg->mutex);
61  free(wg);
62 }
63 
64 void wait_group_add(wait_group_t *wg, int count) {
65  pthread_mutex_lock(&wg->mutex);
66  wg->active_processes += count;
67  pthread_mutex_unlock(&wg->mutex);
68 }
69 
71  // we will set to -1 if caller is trying to decrease count below 0
72  int rc = 0;
73  pthread_mutex_lock(&wg->mutex);
74  // should we guard this with an assert and use compile time NODEBUG ?
75  // TODO(bonedaddy): decide if we should exit here, as this logic would only trigger
76  // if there was an error in program design
77  if (wg->active_processes <= 0) {
78  printf("[warn] invalid call to wait_group_done with 0 active processes\n");
79  rc = -1;
80  } else {
81  // decrease count by 1
82  wg->active_processes--;
83  }
84  pthread_mutex_unlock(&wg->mutex);
85  return rc;
86 }
wait_group_send_signal
void wait_group_send_signal(wait_group_t *wg)
Definition: wait_group.c:27
wait_group_t::active_processes
int active_processes
Definition: wait_group.h:22
wait_group_t::cond_mutex
pthread_mutex_t cond_mutex
Definition: wait_group.h:24
wait_group_done
int wait_group_done(wait_group_t *wg)
used by a process to indicate it is done, decreasing the active process counter we include a return c...
Definition: wait_group.c:70
wait_group_recv_signal
void wait_group_recv_signal(wait_group_t *wg)
Definition: wait_group.c:21
wait_group_reset_signal
void wait_group_reset_signal(wait_group_t *wg)
Definition: wait_group.c:33
wait_group_wait
void wait_group_wait(wait_group_t *wg)
used to wait until current active_processes reaches 0, polling every 0.75 seconds will run free on th...
Definition: wait_group.c:45
wait_group_t::mutex
pthread_mutex_t mutex
Definition: wait_group.h:23
wait_group_t
Definition: wait_group.h:21
wait_group_add
void wait_group_add(wait_group_t *wg, int count)
incremements the total number of active processes managed by this wait group
Definition: wait_group.c:64
wait_group_t::cond_var
pthread_cond_t cond_var
Definition: wait_group.h:25
wait_group_new
wait_group_t * wait_group_new()
returns a new and initialized wait_group_t pointer
Definition: wait_group.c:9