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 #include "It_posix_queue.h"
32
PthreadF01(VOID * arg)33 static VOID *PthreadF01(VOID *arg)
34 {
35 INT32 ret;
36 CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0};
37 struct timespec ts = { 0 };
38
39 ts.tv_sec = 0xffff;
40
41 LOS_AtomicInc(&g_testCount);
42
43 ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts);
44 ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT);
45 ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[4], msgrcd, EXIT); // 4, g_mqueueMsessage buffer index.
46
47 LOS_AtomicInc(&g_testCount);
48 return NULL;
49 EXIT:
50 g_testCount = 0;
51 return NULL;
52 }
53
PthreadF02(VOID * arg)54 static VOID *PthreadF02(VOID *arg)
55 {
56 INT32 ret;
57 CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0};
58 struct timespec ts = { 0 };
59
60 ts.tv_sec = 0xffff;
61
62 LOS_AtomicInc(&g_testCount);
63
64 ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts);
65 ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT);
66 ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[3], msgrcd, EXIT); // 3, g_mqueueMsessage buffer index.
67
68 LOS_AtomicInc(&g_testCount);
69 return NULL;
70 EXIT:
71 g_testCount = 0;
72 return NULL;
73 }
74
PthreadF03(VOID * arg)75 static VOID *PthreadF03(VOID *arg)
76 {
77 INT32 ret;
78 CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0};
79
80 struct timespec ts = { 0 };
81 ts.tv_sec = 0xffff;
82
83 LOS_AtomicInc(&g_testCount);
84
85 ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts);
86 ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT);
87 ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[2], msgrcd, EXIT); // 2, g_mqueueMsessage buffer index.
88
89 LOS_AtomicInc(&g_testCount);
90 return NULL;
91 EXIT:
92 g_testCount = 0;
93 return NULL;
94 }
95
PthreadF04(VOID * arg)96 static VOID *PthreadF04(VOID *arg)
97 {
98 INT32 ret;
99 CHAR msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0};
100 struct timespec ts = { 0 };
101
102 ts.tv_sec = 0xffff;
103
104 LOS_AtomicInc(&g_testCount);
105
106 ret = mq_timedreceive(g_gqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL, &ts);
107 ICUNIT_GOTO_EQUAL(ret, MQUEUE_SHORT_ARRAY_LENGTH, ret, EXIT);
108 ICUNIT_GOTO_STRING_EQUAL(msgrcd, g_mqueueMsessage[1], msgrcd, EXIT);
109
110 LOS_AtomicInc(&g_testCount);
111
112 EXIT:
113 return NULL;
114 }
115
Testcase(VOID)116 static UINT32 Testcase(VOID)
117 {
118 UINT32 ret;
119
120 pthread_t threadA;
121 pthread_attr_t attrA;
122 struct sched_param spA;
123
124 pthread_t threadB;
125 pthread_attr_t attrB;
126 struct sched_param spB;
127
128 pthread_t threadC;
129 pthread_attr_t attrC;
130 struct sched_param spC;
131
132 pthread_t threadD;
133 pthread_attr_t attrD;
134 struct sched_param spD;
135
136 struct mq_attr msgAttr = { 0 };
137 CHAR qName[MQUEUE_STANDARD_NAME_LENGTH] = "";
138
139 msgAttr.mq_msgsize = MQUEUE_STANDARD_NAME_LENGTH;
140 msgAttr.mq_maxmsg = MQUEUE_STANDARD_NAME_LENGTH;
141
142 g_testCount = 0;
143
144 (void)snprintf_s(qName, MQUEUE_STANDARD_NAME_LENGTH, MQUEUE_STANDARD_NAME_LENGTH - 1, \
145 "/mq121_%d", LosCurTaskIDGet());
146
147 g_messageQId = mq_open(qName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &msgAttr);
148 ICUNIT_GOTO_NOT_EQUAL(g_messageQId, (mqd_t)-1, g_messageQId, EXIT);
149
150 ret = pthread_attr_init(&attrA);
151 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
152
153 pthread_attr_setinheritsched(&attrA, PTHREAD_EXPLICIT_SCHED);
154
155 spA.sched_priority = MQUEUE_PTHREAD_PRIORITY_TEST2;
156 ret = pthread_attr_setschedparam(&attrA, &spA);
157 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
158
159 ret = pthread_create(&threadA, &attrA, PthreadF04, NULL);
160 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1);
161
162 ret = pthread_attr_init(&attrB);
163 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT1);
164 pthread_attr_setinheritsched(&attrB, PTHREAD_EXPLICIT_SCHED);
165 spB.sched_priority = 2; // 2, Queue pthread priority.
166 ret = pthread_attr_setschedparam(&attrB, &spB);
167 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2);
168
169 ret = pthread_create(&threadB, &attrB, PthreadF03, NULL);
170 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2);
171
172 ret = pthread_attr_init(&attrC);
173 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2);
174
175 pthread_attr_setinheritsched(&attrC, PTHREAD_EXPLICIT_SCHED);
176
177 spC.sched_priority = 2; // 2, Queue pthread priority.
178 ret = pthread_attr_setschedparam(&attrC, &spC);
179 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3);
180
181 ret = pthread_create(&threadC, &attrC, PthreadF02, NULL);
182 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3);
183
184 ret = pthread_attr_init(&attrD);
185 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3);
186
187 pthread_attr_setinheritsched(&attrD, PTHREAD_EXPLICIT_SCHED);
188
189 spD.sched_priority = 1;
190 ret = pthread_attr_setschedparam(&attrD, &spD);
191 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4);
192
193 ret = pthread_create(&threadD, &attrD, PthreadF01, NULL);
194 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4);
195
196 ret = mq_send(g_messageQId, g_mqueueMsessage[1], MSGLEN, 0);
197 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4);
198
199 ret = mq_send(g_messageQId, g_mqueueMsessage[2], MSGLEN, 0); // 2, g_mqueueMsessage buffer index.
200 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4);
201
202 ret = mq_send(g_messageQId, g_mqueueMsessage[3], MSGLEN, 0); // 3, g_mqueueMsessage buffer index.
203 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4);
204
205 ret = mq_send(g_messageQId, g_mqueueMsessage[4], MSGLEN, 0); // 4, g_mqueueMsessage buffer index.
206 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4);
207
208 TestExtraTaskDelay(3); // 3, Set delay time.
209 ICUNIT_GOTO_EQUAL(g_testCount, 8, g_testCount, EXIT4); // 8, Here, assert the g_testCount.
210
211 ret = pthread_join(threadD, NULL);
212 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4);
213 ret = pthread_attr_destroy(&attrD);
214 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4);
215
216 ret = pthread_join(threadC, NULL);
217 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3);
218 ret = pthread_attr_destroy(&attrC);
219 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT3);
220
221 ret = pthread_join(threadB, NULL);
222 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2);
223 ret = pthread_attr_destroy(&attrB);
224 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT2);
225
226 ret = pthread_join(threadA, NULL);
227 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4);
228 ret = pthread_attr_destroy(&attrA);
229 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT4);
230
231 ret = mq_close(g_messageQId);
232 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
233
234 ret = mq_unlink(qName);
235 ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
236 return MQUEUE_NO_ERROR;
237
238 EXIT4:
239 pthread_join(threadD, NULL);
240 pthread_attr_destroy(&attrD);
241 EXIT3:
242 pthread_join(threadC, NULL);
243 pthread_attr_destroy(&attrC);
244 EXIT2:
245 pthread_join(threadB, NULL);
246 pthread_attr_destroy(&attrA);
247 EXIT1:
248 pthread_join(threadB, NULL);
249 pthread_attr_destroy(&attrA);
250 EXIT:
251 mq_close(g_messageQId);
252 mq_unlink(qName);
253 return MQUEUE_NO_ERROR;
254 }
255
ItPosixQueue121(VOID)256 VOID ItPosixQueue121(VOID) // IT_Layer_ModuleORFeature_No
257 {
258 TEST_ADD_CASE("IT_POSIX_QUEUE_121", Testcase, TEST_POSIX, TEST_QUE, TEST_LEVEL2, TEST_FUNCTION);
259 }
260