[BZ #2821]
[platform/upstream/glibc.git] / nptl / tst-cond22.c
1 #include <pthread.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5
6 static pthread_barrier_t b;
7 static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
8 static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
9
10
11 static void
12 cl (void *arg)
13 {
14   pthread_mutex_unlock (&m);
15 }
16
17
18 static void *
19 tf (void *arg)
20 {
21   if (pthread_mutex_lock (&m) != 0)
22     {
23       printf ("%s: mutex_lock failed\n", __func__);
24       exit (1);
25     }
26   int e = pthread_barrier_wait (&b);
27   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
28     {
29       printf ("%s: barrier_wait failed\n", __func__);
30       exit (1);
31     }
32   pthread_cleanup_push (cl, NULL);
33   if (pthread_cond_wait (&c, &m) != 0)
34     {
35       printf ("%s: cond_wait failed\n", __func__);
36       exit (1);
37     }
38   pthread_cleanup_pop (0);
39   if (pthread_mutex_unlock (&m) != 0)
40     {
41       printf ("%s: mutex_unlock failed\n", __func__);
42       exit (1);
43     }
44   return NULL;
45 }
46
47
48 static int
49 do_test (void)
50 {
51   int status = 0;
52
53   if (pthread_barrier_init (&b, NULL, 2) != 0)
54     {
55       puts ("barrier_init failed");
56       return 1;
57     }
58
59   pthread_t th;
60   if (pthread_create (&th, NULL, tf, NULL) != 0)
61     {
62       puts ("1st create failed");
63       return 1;
64     }
65   int e = pthread_barrier_wait (&b);
66   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
67     {
68       puts ("1st barrier_wait failed");
69       return 1;
70     }
71   if (pthread_mutex_lock (&m) != 0)
72     {
73       puts ("1st mutex_lock failed");
74       return 1;
75     }
76   if (pthread_cond_signal (&c) != 0)
77     {
78       puts ("1st cond_signal failed");
79       return 1;
80     }
81   if (pthread_cancel (th) != 0)
82     {
83       puts ("cancel failed");
84       return 1;
85     }
86   if (pthread_mutex_unlock (&m) != 0)
87     {
88       puts ("1st mutex_unlock failed");
89       return 1;
90     }
91   void *res;
92   if (pthread_join (th, &res) != 0)
93     {
94       puts ("1st join failed");
95       return 1;
96     }
97   if (res != PTHREAD_CANCELED)
98     {
99       puts ("first thread not canceled");
100       status = 1;
101     }
102
103   printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",
104           c.__data.__lock, c.__data.__futex, c.__data.__total_seq,
105           c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,
106           c.__data.__nwaiters, c.__data.__broadcast_seq);
107
108   if (pthread_create (&th, NULL, tf, NULL) != 0)
109     {
110       puts ("2nd create failed");
111       return 1;
112     }
113   e = pthread_barrier_wait (&b);
114   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
115     {
116       puts ("2nd barrier_wait failed");
117       return 1;
118     }
119   if (pthread_mutex_lock (&m) != 0)
120     {
121       puts ("2nd mutex_lock failed");
122       return 1;
123     }
124   if (pthread_cond_signal (&c) != 0)
125     {
126       puts ("2nd cond_signal failed");
127       return 1;
128     }
129   if (pthread_mutex_unlock (&m) != 0)
130     {
131       puts ("2nd mutex_unlock failed");
132       return 1;
133     }
134   if (pthread_join (th, &res) != 0)
135     {
136       puts ("2nd join failed");
137       return 1;
138     }
139   if (res != NULL)
140     {
141       puts ("2nd thread canceled");
142       status = 1;
143     }
144
145   printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",
146           c.__data.__lock, c.__data.__futex, c.__data.__total_seq,
147           c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,
148           c.__data.__nwaiters, c.__data.__broadcast_seq);
149
150   return status;
151 }
152
153 #define TEST_FUNCTION do_test ()
154 #include "../test-skeleton.c"