1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "It_posix_pthread.h"
33
34 #include "It_posix_pthread.h"
35
36 #ifdef __cplusplus
37 #if __cplusplus
38 extern "C" {
39 #endif /* __cpluscplus */
40 #endif /* __cpluscplus */
41
42 pthread_key_t g_key;
43 pthread_key_t g_pthreadKeyTest[PTHREAD_KEY_NUM];
44 pthread_t g_newTh;
45 pthread_t g_newTh2;
46 pthread_once_t g_onceControl = PTHREAD_ONCE_INIT;
47 pthread_cond_t g_pthreadCondTest1 = PTHREAD_COND_INITIALIZER;
48 pthread_mutex_t g_pthreadMutexTest1 = PTHREAD_MUTEX_INITIALIZER;
49 INT32 g_startNum = 0;
50 INT32 g_wakenNum = 0;
51 INT32 g_t1Start = 0;
52 INT32 g_signaled = 0;
53 INT32 g_wokenUp = -1;
54 INT32 g_lowDone = -1;
55 INT32 g_pthreadSem = 0; /* Manual semaphore */
56 INT32 g_pthreadScopeValue = 0;
57 INT32 g_pthreadSchedInherit = 0;
58 INT32 g_pthreadSchedPolicy = 0;
59
60 ScenarIo g_scenarii[] = {
61 CASE_POS(0, 0, 0, 0, 0, 0, 0, 0, "default"),
62 CASE_POS(1, 0, 0, 0, 0, 0, 0, 0, "detached"),
63 CASE_POS(0, 1, 0, 0, 0, 0, 0, 0, "Explicit sched"),
64 CASE_UNK(0, 0, 1, 0, 0, 0, 0, 0, "FIFO Policy"),
65 CASE_UNK(0, 0, 2, 0, 0, 0, 0, 0, "RR Policy"),
66 CASE_UNK(0, 0, 0, 1, 0, 0, 0, 0, "Max sched param"),
67 CASE_UNK(0, 0, 0, -1, 0, 0, 0, 0, "Min sched param"),
68 CASE_POS(0, 0, 0, 0, 1, 0, 0, 0, "Alternative contension scope"),
69 CASE_POS(0, 0, 0, 0, 0, 1, 0, 0, "Alternative stack"),
70 CASE_POS(0, 0, 0, 0, 0, 0, 1, 0, "No guard size"),
71 CASE_UNK(0, 0, 0, 0, 0, 0, 2, 0, "1p guard size"),
72 CASE_POS(0, 0, 0, 0, 0, 0, 0, 1, "Min stack size"),
73 /* Stack play */
74 CASE_POS(0, 0, 0, 0, 0, 0, 1, 1, "Min stack size, no guard"),
75 CASE_UNK(0, 0, 0, 0, 0, 0, 2, 1, "Min stack size, 1p guard"),
76 CASE_POS(1, 0, 0, 0, 0, 1, 0, 0, "Detached, Alternative stack"),
77 CASE_POS(1, 0, 0, 0, 0, 0, 1, 1, "Detached, Min stack size, no guard"),
78 CASE_UNK(1, 0, 0, 0, 0, 0, 2, 1, "Detached, Min stack size, 1p guard"),
79 };
80
81 pthread_t g_pthreadTestTh;
82
ScenarInit(VOID)83 VOID ScenarInit(VOID)
84 {
85 INT32 ret;
86 UINT32 i;
87 INT32 old;
88 long pagesize, minstacksize;
89 long tsa, tss, tps;
90
91 pagesize = sysconf(_SC_PAGESIZE);
92 minstacksize = sysconf(_SC_THREAD_STACK_MIN);
93 tsa = sysconf(_SC_THREAD_ATTR_STACKADDR);
94 tss = sysconf(_SC_THREAD_ATTR_STACKSIZE);
95 tps = sysconf(_SC_THREAD_PRIORITY_SCHEDULING);
96
97 if (pagesize && minstacksize % pagesize) {
98 ICUNIT_ASSERT_EQUAL_VOID(1, 0, errno);
99 }
100
101 for (i = 0; i < NSCENAR; i++) {
102 ret = pthread_attr_init(&g_scenarii[i].ta);
103 ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret);
104
105 if (g_scenarii[i].detached == 1) {
106 ret = pthread_attr_setdetachstate(&g_scenarii[i].ta, PTHREAD_CREATE_DETACHED);
107 ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret);
108
109 ret = pthread_attr_getdetachstate(&g_scenarii[i].ta, &old);
110 ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret);
111 ICUNIT_TRACK_EQUAL(old, PTHREAD_CREATE_JOINABLE, old);
112 }
113
114 /* Sched related attributes */
115 /*
116 * This routine is dependent on the Thread Execution
117 * Scheduling option
118 */
119 if (tps > 0) {
120 if (g_scenarii[i].explicitsched == 1)
121 ret = pthread_attr_setinheritsched(&g_scenarii[i].ta, PTHREAD_EXPLICIT_SCHED);
122 else
123 ret = pthread_attr_setinheritsched(&g_scenarii[i].ta, PTHREAD_INHERIT_SCHED);
124
125 ICUNIT_TRACK_EQUAL(ret, PTHREAD_NO_ERROR, ret);
126 }
127
128 if (tps > 0) {
129 if (g_scenarii[i].schedpolicy == 1)
130 ret = pthread_attr_setschedpolicy(&g_scenarii[i].ta, SCHED_FIFO);
131 if (g_scenarii[i].schedpolicy == 2) // 2, set SCHED_RR as sched mode.
132 ret = pthread_attr_setschedpolicy(&g_scenarii[i].ta, SCHED_RR);
133 ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret);
134
135 if (g_scenarii[i].schedparam != 0) {
136 struct sched_param sp;
137
138 ret = pthread_attr_getschedpolicy(&g_scenarii[i].ta, &old);
139 ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret);
140
141 if (g_scenarii[i].schedparam == 1)
142 sp.sched_priority = sched_get_priority_max(old);
143 if (g_scenarii[i].schedparam == -1)
144 sp.sched_priority = sched_get_priority_min(old);
145
146 ret = pthread_attr_setschedparam(&g_scenarii[i].ta, &sp);
147 ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret);
148 }
149
150 if (tps > 0) {
151 ret = pthread_attr_getscope(&g_scenarii[i].ta, &old);
152 ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret);
153
154 if (g_scenarii[i].altscope != 0) {
155 if (old == PTHREAD_SCOPE_PROCESS)
156 old = PTHREAD_SCOPE_SYSTEM;
157 else
158 old = PTHREAD_SCOPE_PROCESS;
159
160 ret = pthread_attr_setscope(&g_scenarii[i].ta, old);
161 }
162 }
163
164 if ((tss > 0) && (tsa > 0)) {
165 if (g_scenarii[i].altstack != 0) {
166 g_scenarii[i].bottom = malloc(minstacksize + pagesize);
167 ICUNIT_TRACK_NOT_EQUAL(g_scenarii[i].bottom, NULL, g_scenarii[i].bottom);
168 }
169 }
170
171 if (tss > 0) {
172 if (g_scenarii[i].altsize != 0) {
173 ret = pthread_attr_setstacksize(&g_scenarii[i].ta, minstacksize);
174 ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret);
175 }
176 }
177
178 ret = sem_init(&g_scenarii[i].sem, 0, 0);
179 ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret);
180 }
181 }
182 }
183 /*
184 * This function will free all resources consumed
185 * in the scenar_init() routine
186 */
ScenarFini(VOID)187 VOID ScenarFini(VOID)
188 {
189 INT32 ret;
190 UINT32 i;
191
192 for (i = 0; i < NSCENAR; i++) {
193 if (g_scenarii[i].bottom != NULL)
194 free(g_scenarii[i].bottom);
195
196 ret = sem_destroy(&g_scenarii[i].sem);
197 ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret);
198
199 ret = pthread_attr_destroy(&g_scenarii[i].ta);
200 ICUNIT_ASSERT_EQUAL_VOID(ret, PTHREAD_NO_ERROR, ret);
201 }
202 }
203
204 /*
205 * return value of pthread_self() is 0 when
206 * pthread create from LOS_TaskCreate()
207 */
TestPthreadSelf(void)208 pthread_t TestPthreadSelf(void)
209 {
210 pthread_t tid = pthread_self();
211 if (tid == 0) {
212 tid = ((LosTaskCB *)(OsCurrTaskGet()))->taskID;
213 }
214 return tid;
215 }
216
ItSuitePosixPthread()217 VOID ItSuitePosixPthread()
218 {
219 #if defined(LOSCFG_TEST_SMOKE)
220 ItPosixPthread003();
221 ItPosixPthread004();
222 ItPosixPthread005();
223 ItPosixPthread006();
224 ItPosixPthread009();
225 ItPosixPthread018();
226 ItPosixPthread019();
227 ItPosixPthread021();
228 #endif
229
230 #if defined(LOSCFG_TEST_FULL)
231 ItPosixPthread001();
232 ItPosixPthread002();
233 ItPosixPthread007();
234 ItPosixPthread008();
235 ItPosixPthread010();
236 ItPosixPthread011();
237 ItPosixPthread013();
238 ItPosixPthread023();
239 ItPosixPthread028();
240 ItPosixPthread029();
241 ItPosixPthread030();
242 ItPosixPthread031();
243 ItPosixPthread032();
244 ItPosixPthread033();
245 ItPosixPthread034();
246 ItPosixPthread035();
247 ItPosixPthread039();
248 ItPosixPthread040();
249 ItPosixPthread041();
250 ItPosixPthread042();
251 ItPosixPthread044();
252 ItPosixPthread045();
253 ItPosixPthread046();
254 #ifndef LOSCFG_KERNEL_SMP
255 ItPosixPthread047(); // pthread preemption, may not happen on smp
256 #endif
257 ItPosixPthread048();
258 ItPosixPthread049();
259 ItPosixPthread050();
260 ItPosixPthread051();
261 ItPosixPthread056();
262 ItPosixPthread057();
263 ItPosixPthread058();
264 ItPosixPthread060();
265 ItPosixPthread066();
266 ItPosixPthread068();
267 ItPosixPthread069();
268 ItPosixPthread071();
269 ItPosixPthread072();
270 ItPosixPthread073();
271 ItPosixPthread074();
272 ItPosixPthread075();
273 ItPosixPthread078();
274 ItPosixPthread079();
275 ItPosixPthread080();
276 ItPosixPthread081();
277 ItPosixPthread082();
278 ItPosixPthread083();
279 ItPosixPthread084();
280 ItPosixPthread085();
281 ItPosixPthread087();
282 ItPosixPthread088();
283 ItPosixPthread089();
284 ItPosixPthread092();
285 ItPosixPthread095();
286 ItPosixPthread098();
287 ItPosixPthread101();
288 ItPosixPthread102();
289 ItPosixPthread103();
290 ItPosixPthread107();
291 ItPosixPthread108();
292 ItPosixPthread110();
293 ItPosixPthread112();
294 ItPosixPthread116();
295 ItPosixPthread121();
296 ItPosixPthread123();
297 ItPosixPthread124();
298 ItPosixPthread125();
299 ItPosixPthread127();
300 ItPosixPthread128();
301 ItPosixPthread129();
302 ItPosixPthread132();
303 ItPosixPthread133();
304 ItPosixPthread134();
305 ItPosixPthread136();
306 ItPosixPthread138();
307 ItPosixPthread141();
308 ItPosixPthread142();
309 ItPosixPthread144();
310 ItPosixPthread150();
311 ItPosixPthread152();
312 ItPosixPthread154();
313 ItPosixPthread166();
314 ItPosixPthread167();
315 ItPosixPthread173();
316 ItPosixPthread175();
317 ItPosixPthread176();
318 ItPosixPthread177();
319 ItPosixPthread182();
320 ItPosixPthread185();
321 ItPosixPthread186();
322 ItPosixPthread187();
323 ItPosixPthread188();
324 ItPosixPthread193();
325 ItPosixPthread194();
326 ItPosixPthread197();
327 ItPosixPthread198();
328 ItPosixPthread200();
329 ItPosixPthread204();
330 ItPosixPthread205();
331 ItPosixPthread206();
332 ItPosixPthread208();
333 ItPosixPthread209();
334 ItPosixPthread211();
335 ItPosixPthread213();
336 ItPosixPthread214();
337 ItPosixPthread215();
338 ItPosixPthread217();
339 ItPosixPthread218();
340 ItPosixPthread219();
341 ItPosixPthread221();
342 ItPosixPthread224();
343 ItPosixPthread226();
344 ItPosixPthread233();
345 ItPosixPthread237();
346 ItPosixPthread238();
347 ItPosixPthread239();
348 ItPosixPthread240();
349 ItPosixPthread241();
350 ItPosixPthread246();
351 #endif
352 }
353
354 #ifdef __cplusplus
355 #if __cplusplus
356 }
357 #endif /* __cpluscplus */
358 #endif /* __cpluscplus */
359