1 /*
2 * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "xts_ipc.h"
32
33 pthread_mutex_t g_mtx3 = PTHREAD_MUTEX_INITIALIZER;
34 pthread_cond_t g_cond3 = PTHREAD_COND_INITIALIZER;
35
36 LITE_TEST_SUIT(FUTEX, PthreadCondApiTest, PthreadCondApiTestSuite);
37
PthreadCondApiTestSuiteSetUp(void)38 static BOOL PthreadCondApiTestSuiteSetUp(void)
39 {
40 return TRUE;
41 }
42
PthreadCondApiTestSuiteTearDown(void)43 static BOOL PthreadCondApiTestSuiteTearDown(void)
44 {
45 return TRUE;
46 }
47
48 /**
49 * @tc.number SUB_KERNEL_PTHREAD_COND_INIT_0100
50 * @tc.name pthread_cond_init initializes condition variables
51 * @tc.desc [C- SOFTWARE -0200]
52 */
53 LITE_TEST_CASE(PthreadCondApiTestSuite, testPthreadCondInit, Function | MediumTest | Level2)
54 {
55 int ret;
56 pthread_condattr_t condAttr;
57
58 ret = pthread_condattr_init(&condAttr);
59 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
60
61 pthread_cond_t cond1;
62 ret = pthread_cond_init(&cond1, &condAttr);
63 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
64
65 pthread_cond_t cond2;
66 ret = pthread_cond_init(&cond2, NULL);
67 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
68 return 0;
69 }
70
71 /**
72 * @tc.number SUB_KERNEL_PTHREAD_COND_DESTROY_0100
73 * @tc.name pthread_cond_destroy destroy condition variables
74 * @tc.desc [C- SOFTWARE -0200]
75 */
76 LITE_TEST_CASE(PthreadCondApiTestSuite, testPthreadCondDestroy, Function | MediumTest | Level3)
77 {
78 int ret;
79 pthread_condattr_t condAttr;
80 ret = pthread_condattr_init(&condAttr);
81 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
82
83 pthread_cond_t cond1;
84 ret = pthread_cond_init(&cond1, &condAttr);
85 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
86 ret = pthread_cond_destroy(&cond1);
87 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
88
89 pthread_cond_t cond2;
90 ret = pthread_cond_init(&cond2, NULL);
91 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
92 ret = pthread_cond_destroy(&cond2);
93 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
94
95 pthread_cond_t cond3 = PTHREAD_COND_INITIALIZER;
96 ret = pthread_cond_destroy(&cond3);
97 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
98 return 0;
99 }
100
101 /**
102 * @tc.number SUB_KERNEL_PTHREAD_CONDATTR_INIT_0100
103 * @tc.name Init and destroy operations
104 * @tc.desc [C- SOFTWARE -0200]
105 */
106 LITE_TEST_CASE(PthreadCondApiTestSuite, testPthreadCondattrInit, Function | MediumTest | Level2)
107 {
108 int ret;
109 pthread_condattr_t condAttr;
110
111 ret = pthread_condattr_init(&condAttr);
112 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
113 ret = pthread_condattr_destroy(&condAttr);
114 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
115 ret = pthread_condattr_init(&condAttr);
116 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
117 return 0;
118 }
119
120 // pthread_cond_broadcast
ThreadPthreadCondBroadcast1(void * arg)121 void *ThreadPthreadCondBroadcast1(void *arg)
122 {
123 int ret;
124 int *testIntP = (int *)arg;
125 usleep(20); /* 20, common data for test, no special meaning */
126 ret = pthread_mutex_lock(&g_mtx3);
127 ICUNIT_GOTO_EQUAL(ret, POSIX_IPC_NO_ERROR, ret, EXIT);
128 *testIntP = TEST_INTP_SIZE;
129 ret = pthread_cond_broadcast(&g_cond3);
130 ICUNIT_GOTO_EQUAL(ret, POSIX_IPC_NO_ERROR, ret, EXIT);
131 ret = pthread_mutex_unlock(&g_mtx3);
132 ICUNIT_GOTO_EQUAL(ret, POSIX_IPC_NO_ERROR, ret, EXIT);
133 return arg;
134 EXIT:
135 return NULL;
136 }
137
138 // pthread_cond_wait
ThreadPthreadCondBroadcast2(void * arg)139 void *ThreadPthreadCondBroadcast2(void *arg)
140 {
141 int ret;
142 int *testIntP = (int *)arg;
143 ret = pthread_mutex_lock(&g_mtx3);
144 ICUNIT_GOTO_EQUAL(ret, POSIX_IPC_NO_ERROR, ret, EXIT);
145 ret = pthread_cond_wait(&g_cond3, &g_mtx3);
146 ICUNIT_GOTO_EQUAL(ret, POSIX_IPC_NO_ERROR, ret, EXIT);
147 (*testIntP)++;
148 ret = pthread_mutex_unlock(&g_mtx3);
149 ICUNIT_GOTO_EQUAL(ret, POSIX_IPC_NO_ERROR, ret, EXIT);
150 return arg;
151 EXIT:
152 return NULL;
153 }
154
155 /**
156 * @tc.number SUB_KERNEL_PTHREAD_COND_BROADCAST_0100
157 * @tc.name Use pthread_cond_broadcast to release conditional semaphore
158 * @tc.desc [C- SOFTWARE -0200]
159 */
160 LITE_TEST_CASE(PthreadCondApiTestSuite, testPthreadCondBroadcast, Function | MediumTest | Level3)
161 {
162 int ret;
163 pthread_t tid[3]; /* 3, common data for test, no special meaning */
164 int testInt = 0;
165
166 ret = pthread_create(&tid[0], NULL, ThreadPthreadCondBroadcast1, (void*)&testInt);
167 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
168 ret = pthread_create(&tid[1], NULL, ThreadPthreadCondBroadcast2, (void*)&testInt); /* 1, common data for test, no special meaning */
169 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
170 ret = pthread_create(&tid[2], NULL, ThreadPthreadCondBroadcast2, (void*)&testInt); /* 2, common data for test, no special meaning */
171 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
172
173 usleep(100); /* 100, common data for test, no special meaning */
174 int index = (int)(sizeof(tid) / sizeof(tid[0]));
175 for (int i = 0; i < index; i++) {
176 ret = pthread_join(tid[i], NULL);
177 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
178 }
179 EXIT:
180 ret = pthread_cond_destroy(&g_cond3);
181 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
182 ret = pthread_mutex_destroy(&g_mtx3);
183 ICUNIT_ASSERT_EQUAL(ret, POSIX_IPC_NO_ERROR, ret);
184 ICUNIT_ASSERT_EQUAL(testInt, TEST_SEEK_SIZE, testInt);
185 return 0;
186 }
187
188 RUN_TEST_SUITE(PthreadCondApiTestSuite);
189
PosixFutexCondTest(void)190 void PosixFutexCondTest(void)
191 {
192 RUN_ONE_TESTCASE(testPthreadCondInit);
193 RUN_ONE_TESTCASE(testPthreadCondDestroy);
194 RUN_ONE_TESTCASE(testPthreadCondattrInit);
195 RUN_ONE_TESTCASE(testPthreadCondBroadcast);
196 }