1 #pragma once
2 
3 #include "../relacy/pthread.h"
4 
5 
6 
7 struct test_pthread_thread : rl::test_suite<test_pthread_thread, 1>
8 {
9     static size_t const dynamic_thread_count = 2;
10 
11     VAR_T(int) data;
12 
functest_pthread_thread13     static void* func(void* param)
14     {
15         static_cast<test_pthread_thread*>(param)->VAR(data) += 1;
16         return 0;
17     }
18 
threadtest_pthread_thread19     void thread(unsigned)
20     {
21         VAR(data) = 0;
22 
23         pthread_t th1;
24         pthread_create(&th1, 0, &test_pthread_thread::func, this);
25         void* res1 = 0;
26         pthread_join(th1, &res1);
27 
28         RL_ASSERT(VAR(data) == 1);
29 
30         pthread_t th2;
31         pthread_create(&th2, 0, &test_pthread_thread::func, this);
32         void* res2 = 0;
33         pthread_join(th2, &res2);
34 
35         RL_ASSERT(VAR(data) == 2);
36     }
37 };
38 
39 
40 
41 
42 struct test_pthread_mutex : rl::test_suite<test_pthread_mutex, 2>
43 {
44     pthread_mutex_t mtx;
45     VAR_T(int) data;
46 
beforetest_pthread_mutex47     void before()
48     {
49         pthread_mutexattr_t attr;
50         pthread_mutexattr_init(&attr);
51         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
52         pthread_mutex_init(&mtx, &attr);
53         pthread_mutexattr_destroy(&attr);
54         VAR(data) = 0;
55     }
56 
aftertest_pthread_mutex57     void after()
58     {
59         pthread_mutex_destroy(&mtx);
60     }
61 
threadtest_pthread_mutex62     void thread(unsigned /*index*/)
63     {
64         pthread_mutex_lock(&mtx);
65         VAR(data) += 1;
66         pthread_mutex_unlock(&mtx);
67 
68         if (0 == pthread_mutex_try_lock(&mtx))
69         {
70             VAR(data) += 1;
71             pthread_mutex_unlock(&mtx);
72         }
73 
74         //pthread_mutex_timedlock
75     }
76 };
77 
78 
79 
80 
81 struct test_pthread_condvar : rl::test_suite<test_pthread_condvar, 3>
82 {
83     pthread_cond_t cv;
84     pthread_mutex_t mtx;
85     VAR_T(int) stage;
86 
beforetest_pthread_condvar87     void before()
88     {
89         pthread_condattr_t attr;
90         pthread_cond_init(&cv, &attr);
91         pthread_mutex_init(&mtx, 0);
92         VAR(stage) = 0;
93     }
94 
aftertest_pthread_condvar95     void after()
96     {
97         pthread_cond_destroy(&cv);
98         pthread_mutex_destroy(&mtx);
99     }
100 
threadtest_pthread_condvar101     void thread(unsigned index)
102     {
103         if (0 == index)
104         {
105             pthread_mutex_lock(&mtx);
106             VAR(stage) += 1;
107             pthread_cond_broadcast(&cv);
108             while (VAR(stage) != 2)
109                 pthread_cond_wait(&cv, &mtx);
110             pthread_mutex_unlock(&mtx);
111         }
112         else if (1 == index)
113         {
114             pthread_mutex_lock(&mtx);
115             while (VAR(stage) != 1)
116             {
117                 int ts = 1;
118                 pthread_cond_timedwait(&cv, &mtx, &ts);
119             }
120             VAR(stage) += 1;
121             pthread_cond_broadcast(&cv);
122             pthread_mutex_unlock(&mtx);
123         }
124         else if (2 == index)
125         {
126             pthread_mutex_lock(&mtx);
127             while (VAR(stage) != 2)
128                 pthread_cond_wait(&cv, &mtx);
129             pthread_mutex_unlock(&mtx);
130             pthread_cond_signal(&cv);
131         }
132     }
133 };
134 
135 
136 
137 
138 struct test_pthread_condvar2 : rl::test_suite<test_pthread_condvar2, 2>
139 {
140     pthread_cond_t cv1, cv2;
141     pthread_mutex_t mtx1, mtx2;
142     VAR_T(int) stage;
143 
beforetest_pthread_condvar2144     void before()
145     {
146         pthread_cond_init(&cv1, 0);
147         pthread_cond_init(&cv2, 0);
148         pthread_mutex_init(&mtx1, 0);
149         pthread_mutex_init(&mtx2, 0);
150         VAR(stage) = 0;
151     }
152 
aftertest_pthread_condvar2153     void after()
154     {
155         pthread_cond_destroy(&cv1);
156         pthread_cond_destroy(&cv2);
157         pthread_mutex_destroy(&mtx1);
158         pthread_mutex_destroy(&mtx2);
159     }
160 
threadtest_pthread_condvar2161     void thread(unsigned index)
162     {
163         if (0 == index)
164         {
165             pthread_mutex_lock(&mtx1);
166             int ts = 1;
167             pthread_cond_timedwait(&cv1, &mtx1, &ts);
168             pthread_mutex_unlock(&mtx1);
169         }
170         else if (1 == index)
171         {
172             pthread_mutex_lock(&mtx2);
173             int ts = 1;
174             pthread_cond_timedwait(&cv2, &mtx2, &ts);
175             pthread_mutex_unlock(&mtx2);
176         }
177     }
178 };
179 
180 
181 
182 
183 struct test_pthread_rwlock : rl::test_suite<test_pthread_rwlock, 3>
184 {
185     pthread_rwlock_t mtx;
186     VAR_T(int) data;
187 
beforetest_pthread_rwlock188     void before()
189     {
190         pthread_mutexattr_t attr;
191         pthread_mutexattr_init(&attr);
192         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
193         pthread_rwlock_init(&mtx, &attr);
194         pthread_mutexattr_destroy(&attr);
195         VAR(data) = 0;
196     }
197 
aftertest_pthread_rwlock198     void after()
199     {
200         pthread_rwlock_destroy(&mtx);
201     }
202 
threadtest_pthread_rwlock203     void thread(unsigned /*index*/)
204     {
205         pthread_rwlock_wrlock(&mtx);
206         VAR(data) += 1;
207         pthread_rwlock_unlock(&mtx);
208 
209         if (0 == pthread_rwlock_trywrlock(&mtx))
210         {
211             VAR(data) += 1;
212             pthread_rwlock_unlock(&mtx);
213         }
214 
215         pthread_rwlock_rdlock(&mtx);
216         (void)(int)VAR(data);
217         pthread_rwlock_unlock(&mtx);
218 
219         if (0 == pthread_rwlock_tryrdlock(&mtx))
220         {
221             (void)(int)VAR(data);
222             pthread_rwlock_unlock(&mtx);
223         }
224     }
225 };
226 
227 
228 
229 
230 struct test_pthread_sem : rl::test_suite<test_pthread_sem, 2>
231 {
232     sem_t sem1, sem2;
233     VAR_T(int) data;
234 
beforetest_pthread_sem235     void before()
236     {
237         sem_init(&sem1, 0, 0);
238         sem_init(&sem2, 0, 0);
239         VAR(data) = 0;
240     }
241 
aftertest_pthread_sem242     void after()
243     {
244         sem_destroy(&sem1);
245         sem_destroy(&sem2);
246     }
247 
threadtest_pthread_sem248     void thread(unsigned index)
249     {
250         if (index)
251         {
252             VAR(data) = 1;
253             sem_post(&sem1);
254             while (sem_trywait(&sem2))
255             {
256                 assert(errno == EINTR || errno == EAGAIN);
257                 pthread_yield();
258             }
259             RL_ASSERT(VAR(data) == 2);
260             VAR(data) = 3;
261             int count = -1;
262             sem_getvalue(&sem2, &count);
263             RL_ASSERT(count == 0);
264             sem_post(&sem2);
265             sem_getvalue(&sem2, &count);
266             RL_ASSERT(count == 1);
267         }
268         else
269         {
270             while (sem_wait(&sem1))
271                 assert(errno == EINTR);
272             RL_ASSERT(VAR(data) == 1);
273             VAR(data) = 2;
274             sem_post(&sem2);
275         }
276     }
277 };
278 
279 
280 
281 
282