• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <stdio.h>
16 #include <string.h>
17 #include <limits.h>
18 #include <semaphore.h>
19 #include <pthread.h>
20 #include <gtest/gtest.h>
21 #include "utils.h"
22 #include "log.h"
23 
24 using namespace testing::ext;
25 
26 static const unsigned int KERNEL_NS_PER_SECOND = 1000000000;
27 static const unsigned int KERNEL_100MS_BY_NS = 100000000;
28 
29 class SemTest : public::testing::Test {
30 };
31 
32 /**
33  * @tc.number   SUB_KERNEL_IPC_SEM_INIT_0100
34  * @tc.name     Use sem_init initialize the semaphore with 0
35  * @tc.desc     [C- SOFTWARE -0200]
36  */
37 HWTEST_F(SemTest, testSemInitA, Function | MediumTest | Level2)
38 {
39     sem_t sem;
40     int semValue = 0;
41     int testValue = 0;
42 
43     EXPECT_NE(sem_init(&sem, 0, testValue), -1) << "> sem_init errno = " << errno;
44     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
45     EXPECT_TRUE(semValue == testValue);
46     EXPECT_EQ(sem_destroy(&sem), 0) << "> sem_destroy errno = " << errno;
47 }
48 
49 /**
50  * @tc.number   SUB_KERNEL_IPC_SEM_INIT_0110
51  * @tc.name     Use sem_init initialize the semaphore with 1
52  * @tc.desc     [C- SOFTWARE -0200]
53  */
54 HWTEST_F(SemTest, testSemInitB, Function | MediumTest | Level2)
55 {
56     sem_t sem;
57     int semValue = 0;
58     int testValue = 1;
59 
60     EXPECT_NE(sem_init(&sem, 0, testValue), -1) << "> sem_init errno = " << errno;
61     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
62     EXPECT_EQ(semValue, testValue);
63     EXPECT_EQ(sem_destroy(&sem), 0) << "> sem_destroy errno = " << errno;
64 }
65 
66 /**
67  * @tc.number   SUB_KERNEL_IPC_SEM_INIT_0120
68  * @tc.name     Use sem_init initialize the semaphore with 100
69  * @tc.desc     [C- SOFTWARE -0200]
70  */
71 HWTEST_F(SemTest, testSemInitC, Function | MediumTest | Level2)
72 {
73     sem_t sem;
74     int semValue = 0;
75     int testValue = 10;
76 
77     EXPECT_NE(sem_init(&sem, 0, testValue), -1) << "> sem_init errno = " << errno;
78     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
79     EXPECT_EQ(semValue, testValue);
80     EXPECT_EQ(sem_destroy(&sem), 0) << "> sem_destroy errno = " << errno;
81 }
82 
83 /**
84  * @tc.number   SUB_KERNEL_IPC_SEM_POST_0100
85  * @tc.name     sem_post increases the semaphore count
86  * @tc.desc     [C- SOFTWARE -0200]
87  */
88 HWTEST_F(SemTest, testSemPost, Function | MediumTest | Level2)
89 {
90     sem_t sem;
91     int semValue = 0;
92 
93     ASSERT_NE(sem_init(&sem, 0, 0), -1) << "> sem_init errno = " << errno;
94     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
95     EXPECT_EQ(semValue, 0);
96 
97     EXPECT_EQ(sem_post(&sem), 0) << "> sem_post errno = " << errno;
98     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
99     EXPECT_EQ(semValue, 1);
100 
101     EXPECT_EQ(sem_post(&sem), 0) << "> sem_post errno = " << errno;
102     EXPECT_EQ(sem_post(&sem), 0) << "> sem_post errno = " << errno;
103     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
104     EXPECT_EQ(semValue, 3);
105 
106     EXPECT_EQ(sem_destroy(&sem), 0) << "> sem_destroy errno = " << errno;
107 }
108 
109 /**
110  * @tc.number   SUB_KERNEL_IPC_SEM_WAIT_0100
111  * @tc.name     sem_wait get semaphore
112  * @tc.desc     [C- SOFTWARE -0200]
113  */
114 HWTEST_F(SemTest, testSemWait, Function | MediumTest | Level2)
115 {
116     sem_t sem;
117     int semValue = 0;
118 
119     ASSERT_NE(sem_init(&sem, 0, 3), -1) << "> sem_init errno = " << errno;
120     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
121     EXPECT_EQ(semValue, 3);
122 
123     EXPECT_EQ(sem_wait(&sem), 0) << "> sem_wait errno = " << errno;
124     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
125     EXPECT_EQ(semValue, 2);
126 
127     EXPECT_EQ(sem_wait(&sem), 0) << "> sem_wait errno = " << errno;
128     EXPECT_EQ(sem_wait(&sem), 0) << "> sem_wait errno = " << errno;
129     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
130     EXPECT_EQ(semValue, 0);
131 
132     EXPECT_EQ(sem_destroy(&sem), 0) << "> sem_destroy errno = " << errno;
133 }
134 
135 /**
136  * @tc.number   SUB_KERNEL_IPC_SEM_TRYWAIT_0100
137  * @tc.name     sem_trywait get semaphore
138  * @tc.desc     [C- SOFTWARE -0200]
139  */
140 HWTEST_F(SemTest, testSemTryWait, Function | MediumTest | Level2)
141 {
142     sem_t sem;
143     int semValue = 0;
144 
145     ASSERT_NE(sem_init(&sem, 0, 3), -1) << "> sem_init errno = " << errno;
146     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
147     EXPECT_EQ(semValue, 3);
148 
149     EXPECT_EQ(sem_trywait(&sem), 0) << "> sem_trywait errno = " << errno;
150     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
151     EXPECT_EQ(semValue, 2);
152 
153     EXPECT_EQ(sem_trywait(&sem), 0) << "> sem_trywait errno = " << errno;
154     EXPECT_EQ(sem_trywait(&sem), 0) << "> sem_trywait errno = " << errno;
155     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
156     EXPECT_EQ(semValue, 0);
157     EXPECT_EQ(sem_destroy(&sem), 0) << "> sem_destroy errno = " << errno;
158 }
159 
160 /**
161  * @tc.number   SUB_KERNEL_IPC_SEM_DESTROY_0100
162  * @tc.name     check sem_destroy function
163  * @tc.desc     [C- SOFTWARE -0200]
164  */
165 HWTEST_F(SemTest, testSemdestroy, Function | MediumTest | Level3)
166 {
167     sem_t sem;
168     ASSERT_EQ(sem_init(&sem, 0, 0), 0) << "> sem_init errno = " << errno;
169     EXPECT_EQ(sem_destroy(&sem), 0) << "> sem_destroy errno = " << errno;
170 }
171 
ThreadChat(void * arg)172 void *ThreadChat(void *arg)
173 {
174     sem_t *sem = (sem_t*)arg;
175     int semValue = 0;
176 
177     EXPECT_EQ(sem_getvalue(sem, &semValue), 0) << "sem_getvalue errno = " << errno;
178     EXPECT_EQ(semValue, 0);
179     EXPECT_EQ(sem_wait(sem), 0) << "sem_wait errno = " << errno;
180     return nullptr;
181 }
182 
183 /**
184  * @tc.number   SUB_KERNEL_IPC_SEM_CHAT_0100
185  * @tc.name     Inter-thread communication, check sem_wait function
186  * @tc.desc     [C- SOFTWARE -0200]
187  */
188 HWTEST_F(SemTest, testThreadChat, Function | MediumTest | Level3)
189 {
190     pthread_t tid;
191     sem_t sem;
192     int reInt = 0;
193     int semValue = 0;
194 
195     ASSERT_EQ(sem_init(&sem, 0, 0), 0) << "> sem_init errno = " << errno;
196 
197     reInt = pthread_create(&tid, nullptr, ThreadChat, (void*)&sem);
198     ASSERT_EQ(reInt, 0) << "> pthread_create errno, reInt = " << reInt;
199 
200     Msleep(20);
201     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
202     EXPECT_EQ(semValue, 0);
203 
204     EXPECT_EQ(sem_post(&sem), 0) << "sem_post errno = " << errno;
205     EXPECT_EQ(sem_post(&sem), 0) << "sem_post errno = " << errno;
206 
207     Msleep(20);
208     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
209     EXPECT_EQ(semValue, 1);
210 
211     reInt = pthread_join(tid, nullptr);
212     EXPECT_EQ(reInt, 0) << "pthread_join failed, errno=" << reInt;
213     EXPECT_EQ(sem_destroy(&sem), 0) << "> sem_destroy errno = " << errno;
214 }
215 
ThreadSemTryWait(void * arg)216 void *ThreadSemTryWait(void *arg)
217 {
218     sem_t *sem = (sem_t*)arg;
219     int semValue = 0;
220     int loop = 10;
221 
222     EXPECT_EQ(sem_getvalue(sem, &semValue), 0) << "sem_getvalue errno = " << errno;
223     EXPECT_EQ(semValue, 0);
224     for (int i = 0; i < loop; i++) {
225         if (sem_trywait(sem) == 0) {
226             break;
227 
228         }
229         Msleep(10);
230     }
231     return nullptr;
232 }
233 
234 /**
235  * @tc.number   SUB_KERNEL_IPC_SEM_CHAT_0200
236  * @tc.name     basic function test : Inter-thread communication, check sem_trywait function
237  * @tc.desc     [C- SOFTWARE -0200]
238  */
239 HWTEST_F(SemTest, testThreadSemTryWait, Function | MediumTest | Level3)
240 {
241     sem_t sem;
242     int reInt = 0;
243     int semValue = 0;
244 
245     ASSERT_EQ(sem_init(&sem, 0, 0), 0) << "> sem_init errno = " << errno;
246 
247     pthread_t tid;
248     reInt = pthread_create(&tid, nullptr, ThreadSemTryWait, (void*)&sem);
249     ASSERT_EQ(reInt, 0) << "> pthread_create errno, reInt = " << reInt;
250 
251     Msleep(20);
252     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
253     EXPECT_EQ(semValue, 0);
254 
255     EXPECT_EQ(sem_post(&sem), 0) << "sem_post errno = " << errno;
256     EXPECT_EQ(sem_post(&sem), 0) << "sem_post errno = " << errno;
257 
258     reInt = pthread_join(tid, nullptr);
259     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
260     EXPECT_EQ(semValue, 1);
261     EXPECT_EQ(reInt, 0) << "pthread_join failed, errno=" << reInt;
262     EXPECT_EQ(sem_destroy(&sem), 0) << "> sem_destroy errno = " << errno;
263 }
264 
ThreadSemTimedWait(void * arg)265 void *ThreadSemTimedWait(void *arg)
266 {
267     struct timespec ts = {0};
268     sem_t *sem = (sem_t*)arg;
269     int semValue = 0;
270 
271     EXPECT_EQ(sem_getvalue(sem, &semValue), 0) << "sem_getvalue errno = " << errno;
272     EXPECT_EQ(semValue, 0);
273 
274     clock_gettime(CLOCK_REALTIME, &ts);
275     ts.tv_sec = ts.tv_sec + (ts.tv_nsec + KERNEL_100MS_BY_NS) / KERNEL_NS_PER_SECOND;
276     ts.tv_nsec = (ts.tv_nsec + KERNEL_100MS_BY_NS) % KERNEL_NS_PER_SECOND;
277     Msleep(50);
278     EXPECT_EQ(sem_timedwait(sem, &ts), 0) << "sem_timedwait errno = " << errno;
279     EXPECT_EQ(sem_getvalue(sem, &semValue), 0) << "sem_getvalue errno = " << errno;
280 
281     Msleep(100);
282     EXPECT_EQ(semValue, 1);
283     return nullptr;
284 }
285 
286 /**
287  * @tc.number   SUB_KERNEL_IPC_SEM_CHAT_0300
288  * @tc.name     Inter-thread communication, check sem_timedwait function
289  * @tc.desc     [C- SOFTWARE -0200]
290  */
291 HWTEST_F(SemTest, testThreadSemTimedWait, Function | MediumTest | Level3)
292 {
293     pthread_t tid;
294     sem_t sem;
295     int reInt = 0;
296     int semValue = 0;
297 
298     ASSERT_EQ(sem_init(&sem, 0, 0), 0) << "> sem_init errno = " << errno;
299 
300     reInt = pthread_create(&tid, nullptr, ThreadSemTimedWait, (void*)&sem);
301     ASSERT_EQ(reInt, 0) << "> pthread_create errno, reInt = " << reInt;
302 
303     Msleep(10);
304     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
305     EXPECT_EQ(semValue, 0);
306     EXPECT_EQ(sem_post(&sem), 0) << "> sem_post errno = " << errno;
307     EXPECT_EQ(sem_post(&sem), 0) << "> sem_post errno = " << errno;
308 
309     reInt = pthread_join(tid, nullptr);
310     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "> sem_getvalue errno = " << errno;
311     EXPECT_EQ(semValue, 1);
312     EXPECT_EQ(reInt, 0) << "pthread_join failed, errno=" << reInt;
313     EXPECT_EQ(sem_destroy(&sem), 0) << "> sem_destroy errno = " << errno;
314 }
315 
ThreadNThreadWait1(void * arg)316 void *ThreadNThreadWait1(void *arg)
317 {
318     sem_t *sem = (sem_t*)arg;
319     int semValue = 0;
320 
321     Msleep(100);
322     EXPECT_EQ(sem_getvalue(sem, &semValue), 0) << "sem_getvalue errno = " << errno;
323     EXPECT_EQ(semValue, 0);
324     EXPECT_EQ(sem_wait(sem), 0) << "sem_wait errno = " << errno;
325     return nullptr;
326 }
327 
ThreadNThreadWait2(void * arg)328 void *ThreadNThreadWait2(void *arg)
329 {
330     sem_t *sem = (sem_t*)arg;
331     int semValue = 0;
332     EXPECT_EQ(sem_getvalue(sem, &semValue), 0) << "sem_getvalue errno = " << errno;
333     EXPECT_EQ(semValue, 0);
334 
335     Msleep(300);
336     EXPECT_EQ(sem_getvalue(sem, &semValue), 0) << "sem_getvalue errno = " << errno;
337     EXPECT_EQ(semValue, 0);
338 
339     Msleep(200);
340     EXPECT_EQ(sem_getvalue(sem, &semValue), 0) << "sem_getvalue errno = " << errno;
341     EXPECT_EQ(semValue, 1);
342     EXPECT_EQ(sem_wait(sem), 0) << "sem_wait errno = " << errno;
343     return nullptr;
344 }
345 
346 /**
347  * @tc.number   SUB_KERNEL_IPC_SEM_CHAT_0400
348  * @tc.name     N threads wait, main thread post
349  * @tc.desc     [C- SOFTWARE -0200]
350  */
351 HWTEST_F(SemTest, testNThreadWait, Function | MediumTest | Level4)
352 {
353     pthread_t tid1;
354     pthread_t tid2;
355     sem_t sem;
356     int reInt = 0;
357     int semValue = 0;
358 
359     ASSERT_EQ(sem_init(&sem, 0, 0), 0) << "> sem_init errno = " << errno;
360 
361     reInt = pthread_create(&tid1, nullptr, ThreadNThreadWait1, (void*)&sem);
362     ASSERT_EQ(reInt, 0) << "> pthread_create errno, reInt = " << reInt;
363 
364     reInt = pthread_create(&tid2, nullptr, ThreadNThreadWait2, (void*)&sem);
365     ASSERT_EQ(reInt, 0) << "> pthread_create errno, reInt = " << reInt;
366 
367     Msleep(200);
368     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "sem_getvalue errno = " << errno;
369     EXPECT_EQ(semValue, 0);
370     EXPECT_EQ(sem_post(&sem), 0) << "sem_post errno = " << errno;
371 
372     Msleep(20);
373     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "sem_getvalue errno = " << errno;
374     EXPECT_EQ(semValue, 0);
375 
376     Msleep(200);
377     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "sem_getvalue errno = " << errno;
378     EXPECT_EQ(semValue, 0);
379     EXPECT_EQ(sem_post(&sem), 0) << "sem_post errno = " << errno;
380 
381     Msleep(20);
382     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "sem_getvalue errno = " << errno;
383     EXPECT_EQ(semValue, 1);
384 
385     reInt = pthread_join(tid1, nullptr);
386     EXPECT_EQ(reInt, 0) << "pthread_join failed, errno=" << reInt;
387     reInt = pthread_join(tid2, nullptr);
388     EXPECT_EQ(reInt, 0) << "pthread_join failed, errno=" << reInt;
389     EXPECT_EQ(sem_destroy(&sem), 0) << "> sem_destroy errno = " << errno;
390 }
391 
ThreadNThreadPost1(void * arg)392 void *ThreadNThreadPost1(void *arg)
393 {
394     sem_t *sem = (sem_t*)arg;
395     int semValue = 0;
396 
397     Msleep(200);
398     EXPECT_EQ(sem_post(sem), 0) << "sem_post errno = " << errno;
399     Msleep(20);
400     EXPECT_EQ(sem_getvalue(sem, &semValue), 0) << "sem_getvalue errno = " << errno;
401     EXPECT_EQ(semValue, 0);
402     return nullptr;
403 }
404 
ThreadNThreadPost2(void * arg)405 void *ThreadNThreadPost2(void *arg)
406 {
407     sem_t *sem = (sem_t*)arg;
408     int semValue = 0;
409 
410     Msleep(300);
411     EXPECT_EQ(sem_post(sem), 0) << "sem_post errno = " << errno;
412     Msleep(20);
413     EXPECT_EQ(sem_getvalue(sem, &semValue), 0) << "sem_getvalue errno = " << errno;
414     EXPECT_EQ(semValue, 1);
415     return nullptr;
416 }
417 
418 /**
419  * @tc.number   SUB_KERNEL_IPC_SEM_CHAT_0500
420  * @tc.name     N threads post, main thread wait
421  * @tc.desc     [C- SOFTWARE -0200]
422  */
423 HWTEST_F(SemTest, testNThreadPost, Function | MediumTest | Level4)
424 {
425     pthread_t tid1;
426     pthread_t tid2;
427     struct timespec ts = {0};
428     sem_t sem;
429     int reInt = 0;
430     int semValue = 0;
431 
432     ASSERT_EQ(sem_init(&sem, 0, 0), 0) << "> sem_init errno = " << errno;
433 
434     reInt = pthread_create(&tid1, nullptr, ThreadNThreadPost1, (void*)&sem);
435     ASSERT_EQ(reInt, 0) << "> pthread_create errno, reInt = " << reInt;
436 
437     reInt = pthread_create(&tid2, nullptr, ThreadNThreadPost2, (void*)&sem);
438     ASSERT_EQ(reInt, 0) << "> pthread_create errno, reInt = " << reInt;
439 
440     Msleep(100);
441     clock_gettime(CLOCK_REALTIME, &ts);
442     ts.tv_sec = ts.tv_sec + 1;
443     EXPECT_EQ(sem_timedwait(&sem, &ts), 0) << "> sem_timedwait errno = " << errno;
444 
445     Msleep(400);
446     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "sem_getvalue errno = " << errno;
447     EXPECT_EQ(semValue, 1);
448     EXPECT_EQ(sem_trywait(&sem), 0) << "> sem_trywait errno = " << errno;
449     EXPECT_EQ(sem_getvalue(&sem, &semValue), 0) << "sem_getvalue errno = " << errno;
450     EXPECT_EQ(semValue, 0);
451 
452     reInt = pthread_join(tid1, nullptr);
453     EXPECT_EQ(reInt, 0) << "pthread_join failed, errno=" << reInt;
454     reInt = pthread_join(tid2, nullptr);
455     EXPECT_EQ(reInt, 0) << "pthread_join failed, errno=" << reInt;
456     EXPECT_EQ(sem_destroy(&sem), 0) << "> sem_destroy errno = " << errno;
457 }
458