add ere backref regression test
[libc-test] / src / functional / pthread_cond.c
1 #include <pthread.h>
2 #include <string.h>
3 #include "test.h"
4
5 #define TEST(r, f, m) ( \
6         ((r) = (f)) == 0 || (t_error("%s failed: %s (" m ")\n", #f, strerror(r)), 0) )
7
8
9 static void *start_signal(void *arg)
10 {
11         void **args = arg;
12         pthread_mutex_lock(args[1]);
13         pthread_cond_signal(args[0]);
14         pthread_mutex_unlock(args[1]);
15         return 0;
16 }
17
18 static void *start_wait(void *arg)
19 {
20         void **args = arg;
21         pthread_mutex_t *m = args[1];
22         pthread_cond_t *c = args[0];
23         int *x = args[2];
24
25         pthread_mutex_lock(m);
26         while (*x) pthread_cond_wait(c, m);
27         pthread_mutex_unlock(m);
28
29         return 0;
30 }
31
32 int main(void)
33 {
34         pthread_t td, td1, td2, td3;
35         int r;
36         void *res;
37         pthread_mutex_t mtx;
38         pthread_cond_t cond;
39         int foo[1];
40
41         /* Condition variables */
42         TEST(r, pthread_mutex_init(&mtx, 0), "");
43         TEST(r, pthread_cond_init(&cond, 0), "");
44         TEST(r, pthread_mutex_lock(&mtx), "");
45         TEST(r, pthread_create(&td, 0, start_signal, (void *[]){ &cond, &mtx }), "");
46         TEST(r, pthread_cond_wait(&cond, &mtx), "");
47         TEST(r, pthread_join(td, &res), "");
48         TEST(r, pthread_mutex_unlock(&mtx), "");
49         TEST(r, pthread_mutex_destroy(&mtx), "");
50         TEST(r, pthread_cond_destroy(&cond), "");
51
52         /* Condition variables with multiple waiters */
53         TEST(r, pthread_mutex_init(&mtx, 0), "");
54         TEST(r, pthread_cond_init(&cond, 0), "");
55         TEST(r, pthread_mutex_lock(&mtx), "");
56         foo[0] = 1;
57         TEST(r, pthread_create(&td1, 0, start_wait, (void *[]){ &cond, &mtx, foo }), "");
58         TEST(r, pthread_create(&td2, 0, start_wait, (void *[]){ &cond, &mtx, foo }), "");
59         TEST(r, pthread_create(&td3, 0, start_wait, (void *[]){ &cond, &mtx, foo }), "");
60         TEST(r, pthread_mutex_unlock(&mtx), "");
61         nanosleep(&(struct timespec){.tv_nsec=1000000}, 0);
62         foo[0] = 0;
63         TEST(r, pthread_mutex_lock(&mtx), "");
64         TEST(r, pthread_cond_signal(&cond), "");
65         TEST(r, pthread_mutex_unlock(&mtx), "");
66         TEST(r, pthread_mutex_lock(&mtx), "");
67         TEST(r, pthread_cond_signal(&cond), "");
68         TEST(r, pthread_mutex_unlock(&mtx), "");
69         TEST(r, pthread_mutex_lock(&mtx), "");
70         TEST(r, pthread_cond_signal(&cond), "");
71         TEST(r, pthread_mutex_unlock(&mtx), "");
72         TEST(r, pthread_join(td1, 0), "");
73         TEST(r, pthread_join(td2, 0), "");
74         TEST(r, pthread_join(td3, 0), "");
75         TEST(r, pthread_mutex_destroy(&mtx), "");
76         TEST(r, pthread_cond_destroy(&cond), "");
77
78         /* Condition variables with broadcast signals */
79         TEST(r, pthread_mutex_init(&mtx, 0), "");
80         TEST(r, pthread_cond_init(&cond, 0), "");
81         TEST(r, pthread_mutex_lock(&mtx), "");
82         foo[0] = 1;
83         TEST(r, pthread_create(&td1, 0, start_wait, (void *[]){ &cond, &mtx, foo }), "");
84         TEST(r, pthread_create(&td2, 0, start_wait, (void *[]){ &cond, &mtx, foo }), "");
85         TEST(r, pthread_create(&td3, 0, start_wait, (void *[]){ &cond, &mtx, foo }), "");
86         TEST(r, pthread_mutex_unlock(&mtx), "");
87         nanosleep(&(struct timespec){.tv_nsec=1000000}, 0);
88         TEST(r, pthread_mutex_lock(&mtx), "");
89         foo[0] = 0;
90         TEST(r, pthread_mutex_unlock(&mtx), "");
91         TEST(r, pthread_cond_broadcast(&cond), "");
92         TEST(r, pthread_join(td1, 0), "");
93         TEST(r, pthread_join(td2, 0), "");
94         TEST(r, pthread_join(td3, 0), "");
95         TEST(r, pthread_mutex_destroy(&mtx), "");
96         TEST(r, pthread_cond_destroy(&cond), "");
97
98         return t_status;
99 }