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