1#include <pthread.h>
2#include <stdbool.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <unistd.h>
7#include <atomic.h>
8
9static pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
10static pthread_mutex_t mut1 = PTHREAD_MUTEX_INITIALIZER;
11
12static pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
13static pthread_mutex_t mut2 = PTHREAD_MUTEX_INITIALIZER;
14
15static bool last_round;
16static int ntogo;
17static bool alldone;
18
19
20static void *
21cons (void *arg)
22{
23 pthread_mutex_lock (mutex: &mut1);
24
25 do
26 {
27 if (atomic_decrement_and_test (&ntogo))
28 {
29 pthread_mutex_lock (mutex: &mut2);
30 alldone = true;
31 pthread_cond_signal (cond: &cond2);
32 pthread_mutex_unlock (mutex: &mut2);
33 }
34
35 pthread_cond_wait (cond: &cond1, mutex: &mut1);
36 }
37 while (! last_round);
38
39 pthread_mutex_unlock (mutex: &mut1);
40
41 return NULL;
42}
43
44
45int
46main (int argc, char *argv[])
47{
48 int opt;
49 int err;
50 int nthreads = 10;
51 int nrounds = 100;
52 bool keeplock = false;
53
54 while ((opt = getopt (argc: argc, argv: argv, shortopts: "n:r:k")) != -1)
55 switch (opt)
56 {
57 case 'n':
58 nthreads = atol (nptr: optarg);
59 break;
60 case 'r':
61 nrounds = atol (nptr: optarg);
62 break;
63 case 'k':
64 keeplock = true;
65 break;
66 }
67
68 ntogo = nthreads;
69
70 pthread_t th[nthreads];
71 int i;
72 for (i = 0; __builtin_expect (i < nthreads, 1); ++i)
73 if (__glibc_unlikely ((err = pthread_create (&th[i], NULL, cons, (void *) (long) i)) != 0))
74 printf (format: "pthread_create: %s\n", strerror (errnum: err));
75
76 for (i = 0; __builtin_expect (i < nrounds, 1); ++i)
77 {
78 pthread_mutex_lock (mutex: &mut2);
79 while (! alldone)
80 pthread_cond_wait (cond: &cond2, mutex: &mut2);
81 pthread_mutex_unlock (mutex: &mut2);
82
83 pthread_mutex_lock (mutex: &mut1);
84 if (! keeplock)
85 pthread_mutex_unlock (mutex: &mut1);
86
87 ntogo = nthreads;
88 alldone = false;
89 if (i + 1 >= nrounds)
90 last_round = true;
91
92 pthread_cond_broadcast (cond: &cond1);
93
94 if (keeplock)
95 pthread_mutex_unlock (mutex: &mut1);
96 }
97
98 for (i = 0; i < nthreads; ++i)
99 if ((err = pthread_join (th: th[i], NULL)) != 0)
100 printf (format: "pthread_create: %s\n", strerror (errnum: err));
101
102 return 0;
103}
104

source code of glibc/nptl/cond-perf.c