#include #include #include #include #include /* the number of threads */ int num_threads; /* the counter and semaphores needed for the barrier */ int counter = 0; sem_t count_sem; sem_t barrier_sem; /* the function called for each thread */ void* worker(void* idp) { /* get our thread id */ int id = * (int*) idp; /* we start to work */ printf("Thread %d starting!\n", id); /* simulate the threads taking slightly different amounts of time by sleeping * for our thread id seconds */ sleep(id); printf("Thread %d is done its work!\n", id); /***************** begin barrier here *****************/ /* wait for the counter first */ sem_wait(&count_sem); /* check if we are the last one to the barrier */ if (counter == (num_threads - 1)) { /* we are the last thread */ /* reset counter and free it */ counter = 0; sem_post(&count_sem); /* post once for each waiting thread */ for (int i = 0; i < (num_threads - 1); i++) { sem_post(&barrier_sem); } } else { /* we are NOT the last thread */ /* increment the counter and free it */ counter++; sem_post(&count_sem); /* now wait to be freed */ sem_wait(&barrier_sem); } /***************** end barrier here *****************/ printf("Thread %d is past the barrier!\n", id); pthread_exit(NULL); } int main (int argc, char** argv) { /* get the number of threads */ if (argc < 2) { printf("Pass the number of threads to use!\n"); pthread_exit(0); } else { num_threads = atoi(argv[1]); } /* setup the semaphores */ sem_init(&barrier_sem, 0, 0); sem_init(&count_sem, 0, 1); /* an array of threads */ pthread_t threads[num_threads]; int ids[num_threads]; /* spawn all threads */ for (int i = 0; i < num_threads; i++) { ids[i] = i; pthread_create(&threads[i], NULL, worker, &ids[i]); } /* join all threads */ for (int i = 0; i < num_threads; i++) { pthread_join(threads[i], NULL); } pthread_exit(0); }