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