• 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 
16 #include "hc_condition_test.h"
17 
18 #include <hctest.h>
19 #include <parameter.h>
20 #include <pthread.h>
21 #include <securec.h>
22 #include <semaphore.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 
26 #include "print_log.h"
27 #include "test_timer.h"
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 typedef struct {
34     pthread_cond_t *cond;
35     pthread_mutex_t *mutex;
36     sem_t *sem;
37     int32_t semState;
38     int32_t condState;
39 } ThreadTestArgs;
40 
41 #define REQUIRED_SEM_DEFAULT_COUNT 20
42 #define REQUIRED_SEM_COUNT 20
43 #define REQUIRED_ATTR_DEFAULT_COUNT 20
44 #define REQUIRED_ATTR_COUNT 20
45 
46 /* sem_wait thread test */
ThreadSemWait(void * args)47 static void *ThreadSemWait(void *args)
48 {
49     LOGI("into ThreadSemWait");
50     int res;
51     ThreadTestArgs *semArgs = (ThreadTestArgs *)args;
52     TEST_ASSERT_NOT_NULL(semArgs->sem);
53     TEST_ASSERT_NOT_EQUAL(0, semArgs->semState);
54     RUN_AND_PRINT_ELAPSED_TIME(res, sem_wait((sem_t *)semArgs->sem));
55     // after sem_post
56     LOGI("sem_wait result = %d", res);
57     TEST_ASSERT_EQUAL(0, res);
58     semArgs->semState = 0;
59     return args;
60 }
61 
62 /* sem_post thread test */
ThreadSemPost(void * args)63 static void *ThreadSemPost(void *args)
64 {
65     LOGI("into ThreadSemPost");
66     int res;
67     ThreadTestArgs *semArgs = (ThreadTestArgs *)args;
68     TEST_ASSERT_NOT_NULL(semArgs->sem);
69     RUN_AND_PRINT_ELAPSED_TIME(res, sem_post((sem_t *)semArgs->sem));
70     LOGI("sem_post result = %d", res);
71     TEST_ASSERT_EQUAL(0, res);
72     return args;
73 }
74 
75 /* pthread_cond_wait thread test */
ThreadCondWait(void * args)76 static void *ThreadCondWait(void *args)
77 {
78     LOGI("into ThreadCondWait");
79     int res;
80     ThreadTestArgs *condArgs = (ThreadTestArgs *)args;
81     TEST_ASSERT_NOT_NULL(condArgs->cond);
82     TEST_ASSERT_NOT_NULL(condArgs->mutex);
83     TEST_ASSERT_NOT_EQUAL(0, condArgs->condState);
84     RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_wait(condArgs->cond, condArgs->mutex));
85     // after pthread_cond_signal
86     LOGI("pthread_cond_wait result = %d", res);
87     TEST_ASSERT_EQUAL(0, res);
88     condArgs->condState = 0;
89     return args;
90 }
91 
92 /* pthread_cond_signal thread test */
ThreadCondSignal(void * args)93 static void *ThreadCondSignal(void *args)
94 {
95     LOGI("into ThreadCondSignal");
96     int res;
97     ThreadTestArgs *testArgs = (ThreadTestArgs *)args;
98     TEST_ASSERT_NOT_NULL(testArgs->cond);
99     TEST_ASSERT_NOT_NULL(testArgs->mutex);
100     RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_signal(testArgs->cond));
101     LOGI("pthread_cond_signal result = %d", res);
102     return args;
103 }
104 
105 /* sem_init and sem_destroy test */
TestSemInit(int count)106 static void TestSemInit(int count)
107 {
108     int res;
109     sem_t sem[count];
110     res = memset_s(sem, sizeof(sem), 0, sizeof(sem));
111     TEST_ASSERT_EQUAL(0, res);
112 
113     for (int i = 0; i < count; ++i) {
114         RUN_AND_PRINT_ELAPSED_TIME(res, sem_init(&sem[i], 0, 0));
115         LOGI("sem_init result = %d", res);
116         TEST_ASSERT_EQUAL(0, res);
117     }
118     for (int i = 0; i < count; ++i) {
119         RUN_AND_PRINT_ELAPSED_TIME(res, sem_destroy(&sem[i]));
120         LOGI("sem_destroy result = %d", res);
121         TEST_ASSERT_EQUAL(0, res);
122     }
123 }
124 
125 /* sem_wait test */
TestSemWait(int count)126 static void TestSemWait(int count)
127 {
128     int res;
129     pthread_attr_t attr;
130     pthread_t threads[count];
131 
132     res = memset_s(threads, sizeof(threads), 0, sizeof(threads));
133     TEST_ASSERT_EQUAL(0, res);
134 
135     sem_t sem = {0};
136     TEST_ASSERT_EQUAL(0, res);
137 
138     RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_init(&attr));
139     TEST_ASSERT_EQUAL(0, res);
140 
141     for (int i = 0; i < count; ++i) {
142         RUN_AND_PRINT_ELAPSED_TIME(res, sem_init(&sem, 0, 0));
143         LOGI("sem_init result = %d", res);
144         ThreadTestArgs args = {
145             .sem = &sem,
146             .semState = -1,
147         };
148         TEST_ASSERT_EQUAL(0, res);
149         /* create phread to wait */
150         RUN_AND_PRINT_ELAPSED_TIME(res, pthread_create(&threads[i], &attr, ThreadSemWait, &args));
151         LOGI("create sem_wait thread result = %d", res);
152         int sleepSeconds = rand() % (WAIT_IN_SEM_SECONDS_MAX - WAIT_IN_SEM_SECONDS_MIN) + WAIT_IN_SEM_SECONDS_MIN;
153         sleep(sleepSeconds);
154         /* sleep seconds then create thread to post */
155         RUN_AND_PRINT_ELAPSED_TIME(res, pthread_create(&threads[i], &attr, ThreadSemPost, &args));
156         LOGI("create sem_post thread result = %d", res);
157         TEST_ASSERT_EQUAL(0, res);
158         sleep(sleepSeconds);
159         TEST_ASSERT_EQUAL(0, args.semState);
160     }
161 }
162 
163 /* sem_post test */
TestSemPost(int count)164 static void TestSemPost(int count)
165 {
166     int res;
167     sem_t sem[count];
168     res = memset_s(sem, sizeof(sem), 0, sizeof(sem));
169     TEST_ASSERT_EQUAL(0, res);
170 
171     for (int i = 0; i < count; ++i) {
172         RUN_AND_PRINT_ELAPSED_TIME(res, sem_init(&sem[i], 0, 0));
173         LOGI("sem_init int TestSemPost result = %d", res);
174         TEST_ASSERT_EQUAL(0, res);
175         RUN_AND_PRINT_ELAPSED_TIME(res, sem_post(&sem[i]));
176         LOGI("sem_post result = %d", res);
177         TEST_ASSERT_EQUAL(0, res);
178     }
179     for (int i = 0; i < count; ++i) {
180         RUN_AND_PRINT_ELAPSED_TIME(res, sem_post(&sem[i]));
181         LOGI("sem_post result = %d", res);
182         TEST_ASSERT_EQUAL(0, res);
183     }
184     for (int i = 0; i < count; ++i) {
185         RUN_AND_PRINT_ELAPSED_TIME(res, sem_destroy(&sem[i]));
186         LOGI("sem_destroy in TestSemPost result = %d", res);
187         TEST_ASSERT_EQUAL(0, res);
188     }
189 }
190 
191 /* pthread_condattr_init and pthread_condattr_destroy test */
TestAttrConInit(int count)192 static void TestAttrConInit(int count)
193 {
194     int res;
195     pthread_condattr_t attr[count];
196     res = memset_s(attr, sizeof(attr), 0, sizeof(attr));
197     TEST_ASSERT_EQUAL(0, res);
198     for (int i = 0; i < count; ++i) {
199         RUN_AND_PRINT_ELAPSED_TIME(res, pthread_condattr_init(&attr[i]));
200         LOGI("pthread_condattr_init result = %d", res);
201         TEST_ASSERT_EQUAL(0, res);
202     }
203 
204     for (int i = 0; i < count; ++i) {
205         RUN_AND_PRINT_ELAPSED_TIME(res, pthread_condattr_destroy(&attr[i]));
206         LOGI("pthread_condattr_destroy result = %d", res);
207         TEST_ASSERT_EQUAL(0, res);
208     }
209 }
210 
211 /* pthread_cond_init and pthread_cond_destroy test */
TestConInit(int count)212 static void TestConInit(int count)
213 {
214     int res;
215     pthread_condattr_t attr = {0};
216     pthread_cond_t cond[count];
217     RUN_AND_PRINT_ELAPSED_TIME(res, pthread_condattr_init(&attr));
218     LOGI("pthread_condattr_init in TestConInit result = %d", res);
219     TEST_ASSERT_EQUAL(0, res);
220     res = memset_s(cond, sizeof(cond), 0, sizeof(cond));
221     TEST_ASSERT_EQUAL(0, res);
222 
223     for (int i = 0; i < count; ++i) {
224         RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_init(&cond[i], &attr));
225         LOGI("pthread_cond_init result = %d", res);
226         TEST_ASSERT_EQUAL(0, res);
227     }
228     for (int i = 0; i < count; ++i) {
229         RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_destroy(&cond[i]));
230         LOGI("pthread_cond_destroy result = %d", res);
231         TEST_ASSERT_EQUAL(0, res);
232     }
233 }
234 
235 /* pthread_cond_wait and pthread_cond_signal test */
TestConWait(int count)236 static void TestConWait(int count)
237 {
238     int res;
239     pthread_attr_t pthreadAttr;
240     pthread_condattr_t attr = {0};
241     pthread_cond_t cond;
242     pthread_mutex_t mutex;
243     pthread_t threads[count];
244     res = memset_s(&mutex, sizeof(mutex), 0, sizeof(mutex));
245     TEST_ASSERT_EQUAL(0, res);
246     res = memset_s(threads, sizeof(threads), 0, sizeof(threads));
247     TEST_ASSERT_EQUAL(0, res);
248     RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_init(&pthreadAttr));
249     TEST_ASSERT_EQUAL(0, res);
250     // init attr and cond and mutex
251     RUN_AND_PRINT_ELAPSED_TIME(res, pthread_condattr_init(&attr));
252     LOGI("pthread_condattr_init in TestConWait result = %d", res);
253     RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_init(&cond, &attr));
254     LOGI("pthread_cond_init in TestConWait result = %d", res);
255 
256     for (int i = 0; i < count; ++i) {
257         ThreadTestArgs args = {
258             .cond = &cond,
259             .mutex = &mutex,
260             .condState = -1,
261         };
262         /* create phread to wait */
263         RUN_AND_PRINT_ELAPSED_TIME(res, pthread_create(&threads[i], &pthreadAttr, ThreadCondWait, &args));
264         LOGI("create pthread_cond_wait thread result = %d", res);
265         TEST_ASSERT_EQUAL(0, res);
266         int sleepSeconds = rand() % (WAIT_IN_SEM_SECONDS_MAX - WAIT_IN_SEM_SECONDS_MIN) + WAIT_IN_SEM_SECONDS_MIN;
267         sleep(sleepSeconds);
268         /* sleep seconds then create thread to send signal */
269         RUN_AND_PRINT_ELAPSED_TIME(res, pthread_create(&threads[i], &pthreadAttr, ThreadCondSignal, &args));
270         LOGI("create pthread_cond_signal thread result = %d", res);
271         TEST_ASSERT_EQUAL(0, res);
272         sleep(sleepSeconds);
273         TEST_ASSERT_EQUAL(0, args.condState);
274     }
275 }
276 
277 /* pthread_cond_signal test */
TestConSignal(int count)278 static void TestConSignal(int count)
279 {
280     int res;
281     pthread_condattr_t attr = {0};
282     pthread_cond_t cond;
283     RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_init(&cond, &attr));
284     LOGI("pthread_cond_init in TestConWait result = %d", res);
285     TEST_ASSERT_EQUAL(0, res);
286     for (int i = 0; i < count; ++i) {
287         RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_signal(&cond));
288         LOGI("pthread_cond_signal result = %d", res);
289         TEST_ASSERT_EQUAL(0, res);
290     }
291 }
292 
293 /* test semaphore with sem series */
TestHcSemCondition(void)294 void TestHcSemCondition(void)
295 {
296     TestSemInit(REQUIRED_SEM_DEFAULT_COUNT);
297     TestSemPost(REQUIRED_SEM_DEFAULT_COUNT);
298     TestSemWait(REQUIRED_SEM_DEFAULT_COUNT);
299 }
300 
301 /* test semaphore with phread cond */
TestHcPthreadCondition(void)302 void TestHcPthreadCondition(void)
303 {
304     TestConWait(REQUIRED_ATTR_DEFAULT_COUNT);
305     TestAttrConInit(REQUIRED_ATTR_DEFAULT_COUNT);
306     TestConInit(REQUIRED_ATTR_DEFAULT_COUNT);
307     TestConSignal(REQUIRED_ATTR_DEFAULT_COUNT);
308 }
309 
310 #ifdef __cplusplus
311 }
312 #endif
313