1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2023 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 "los_queue_pri.h"
33 #include "los_queue_debug_pri.h"
34 #include "los_task_pri.h"
35 #include "los_sched_pri.h"
36 #include "los_spinlock.h"
37 #include "los_mp.h"
38 #include "los_percpu_pri.h"
39 #include "los_hook.h"
40 #ifdef LOSCFG_IPC_CONTAINER
41 #include "los_ipc_container_pri.h"
42 #endif
43
44 #ifdef LOSCFG_BASE_IPC_QUEUE
45 #if (LOSCFG_BASE_IPC_QUEUE_LIMIT <= 0)
46 #error "queue maxnum cannot be zero"
47 #endif /* LOSCFG_BASE_IPC_QUEUE_LIMIT <= 0 */
48
49 #ifndef LOSCFG_IPC_CONTAINER
50 LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL;
51 LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList;
52 #define FREE_QUEUE_LIST g_freeQueueList
53 #endif
54
OsAllQueueCBInit(LOS_DL_LIST * freeQueueList)55 LITE_OS_SEC_TEXT_INIT LosQueueCB *OsAllQueueCBInit(LOS_DL_LIST *freeQueueList)
56 {
57 UINT32 index;
58
59 if (freeQueueList == NULL) {
60 return NULL;
61 }
62
63 UINT32 size = LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB);
64 /* system resident memory, don't free */
65 LosQueueCB *allQueue = (LosQueueCB *)LOS_MemAlloc(m_aucSysMem0, size);
66 if (allQueue == NULL) {
67 return NULL;
68 }
69 (VOID)memset_s(allQueue, size, 0, size);
70 LOS_ListInit(freeQueueList);
71 for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) {
72 LosQueueCB *queueNode = ((LosQueueCB *)allQueue) + index;
73 queueNode->queueID = index;
74 LOS_ListTailInsert(freeQueueList, &queueNode->readWriteList[OS_QUEUE_WRITE]);
75 }
76
77 #ifndef LOSCFG_IPC_CONTAINER
78 if (OsQueueDbgInitHook() != LOS_OK) {
79 (VOID)LOS_MemFree(m_aucSysMem0, allQueue);
80 return NULL;
81 }
82 #endif
83 return allQueue;
84 }
85
86 /*
87 * Description : queue initial
88 * Return : LOS_OK on success or error code on failure
89 */
OsQueueInit(VOID)90 LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID)
91 {
92 #ifndef LOSCFG_IPC_CONTAINER
93 g_allQueue = OsAllQueueCBInit(&g_freeQueueList);
94 if (g_allQueue == NULL) {
95 return LOS_ERRNO_QUEUE_NO_MEMORY;
96 }
97 #endif
98 return LOS_OK;
99 }
100
LOS_QueueCreate(CHAR * queueName,UINT16 len,UINT32 * queueID,UINT32 flags,UINT16 maxMsgSize)101 LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *queueName, UINT16 len, UINT32 *queueID,
102 UINT32 flags, UINT16 maxMsgSize)
103 {
104 LosQueueCB *queueCB = NULL;
105 UINT32 intSave;
106 LOS_DL_LIST *unusedQueue = NULL;
107 UINT8 *queue = NULL;
108 UINT16 msgSize;
109
110 (VOID)queueName;
111 (VOID)flags;
112
113 if (queueID == NULL) {
114 return LOS_ERRNO_QUEUE_CREAT_PTR_NULL;
115 }
116
117 if (maxMsgSize > (OS_NULL_SHORT - sizeof(UINT32))) {
118 return LOS_ERRNO_QUEUE_SIZE_TOO_BIG;
119 }
120
121 if ((len == 0) || (maxMsgSize == 0)) {
122 return LOS_ERRNO_QUEUE_PARA_ISZERO;
123 }
124
125 msgSize = maxMsgSize + sizeof(UINT32);
126 /*
127 * Memory allocation is time-consuming, to shorten the time of disable interrupt,
128 * move the memory allocation to here.
129 */
130 queue = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, (UINT32)len * msgSize);
131 if (queue == NULL) {
132 return LOS_ERRNO_QUEUE_CREATE_NO_MEMORY;
133 }
134
135 SCHEDULER_LOCK(intSave);
136 if (LOS_ListEmpty(&FREE_QUEUE_LIST)) {
137 SCHEDULER_UNLOCK(intSave);
138 OsQueueCheckHook();
139 (VOID)LOS_MemFree(m_aucSysMem1, queue);
140 return LOS_ERRNO_QUEUE_CB_UNAVAILABLE;
141 }
142
143 unusedQueue = LOS_DL_LIST_FIRST(&FREE_QUEUE_LIST);
144 LOS_ListDelete(unusedQueue);
145 queueCB = GET_QUEUE_LIST(unusedQueue);
146 queueCB->queueLen = len;
147 queueCB->queueSize = msgSize;
148 queueCB->queueHandle = queue;
149 queueCB->queueState = OS_QUEUE_INUSED;
150 queueCB->readWriteableCnt[OS_QUEUE_READ] = 0;
151 queueCB->readWriteableCnt[OS_QUEUE_WRITE] = len;
152 queueCB->queueHead = 0;
153 queueCB->queueTail = 0;
154 LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_READ]);
155 LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_WRITE]);
156 LOS_ListInit(&queueCB->memList);
157
158 OsQueueDbgUpdateHook(queueCB->queueID, OsCurrTaskGet()->taskEntry);
159 SCHEDULER_UNLOCK(intSave);
160
161 *queueID = queueCB->queueID;
162 OsHookCall(LOS_HOOK_TYPE_QUEUE_CREATE, queueCB);
163 return LOS_OK;
164 }
165
OsQueueReadParameterCheck(UINT32 queueID,const VOID * bufferAddr,const UINT32 * bufferSize,UINT32 timeout)166 STATIC LITE_OS_SEC_TEXT UINT32 OsQueueReadParameterCheck(UINT32 queueID, const VOID *bufferAddr,
167 const UINT32 *bufferSize, UINT32 timeout)
168 {
169 if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
170 return LOS_ERRNO_QUEUE_INVALID;
171 }
172 if ((bufferAddr == NULL) || (bufferSize == NULL)) {
173 return LOS_ERRNO_QUEUE_READ_PTR_NULL;
174 }
175
176 if ((*bufferSize == 0) || (*bufferSize > (OS_NULL_SHORT - sizeof(UINT32)))) {
177 return LOS_ERRNO_QUEUE_READSIZE_IS_INVALID;
178 }
179
180 OsQueueDbgTimeUpdateHook(queueID);
181
182 if (timeout != LOS_NO_WAIT) {
183 if (OS_INT_ACTIVE) {
184 return LOS_ERRNO_QUEUE_READ_IN_INTERRUPT;
185 }
186 }
187 return LOS_OK;
188 }
189
OsQueueWriteParameterCheck(UINT32 queueID,const VOID * bufferAddr,const UINT32 * bufferSize,UINT32 timeout)190 STATIC LITE_OS_SEC_TEXT UINT32 OsQueueWriteParameterCheck(UINT32 queueID, const VOID *bufferAddr,
191 const UINT32 *bufferSize, UINT32 timeout)
192 {
193 if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
194 return LOS_ERRNO_QUEUE_INVALID;
195 }
196
197 if (bufferAddr == NULL) {
198 return LOS_ERRNO_QUEUE_WRITE_PTR_NULL;
199 }
200
201 if (*bufferSize == 0) {
202 return LOS_ERRNO_QUEUE_WRITESIZE_ISZERO;
203 }
204
205 OsQueueDbgTimeUpdateHook(queueID);
206
207 if (timeout != LOS_NO_WAIT) {
208 if (OS_INT_ACTIVE) {
209 return LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT;
210 }
211 }
212 return LOS_OK;
213 }
214
OsQueueBufferOperate(LosQueueCB * queueCB,UINT32 operateType,VOID * bufferAddr,UINT32 * bufferSize)215 STATIC VOID OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize)
216 {
217 UINT8 *queueNode = NULL;
218 UINT32 msgDataSize;
219 UINT16 queuePosition;
220
221 /* get the queue position */
222 switch (OS_QUEUE_OPERATE_GET(operateType)) {
223 case OS_QUEUE_READ_HEAD:
224 queuePosition = queueCB->queueHead;
225 ((queueCB->queueHead + 1) == queueCB->queueLen) ? (queueCB->queueHead = 0) : (queueCB->queueHead++);
226 break;
227 case OS_QUEUE_WRITE_HEAD:
228 (queueCB->queueHead == 0) ? (queueCB->queueHead = queueCB->queueLen - 1) : (--queueCB->queueHead);
229 queuePosition = queueCB->queueHead;
230 break;
231 case OS_QUEUE_WRITE_TAIL:
232 queuePosition = queueCB->queueTail;
233 ((queueCB->queueTail + 1) == queueCB->queueLen) ? (queueCB->queueTail = 0) : (queueCB->queueTail++);
234 break;
235 default: /* read tail, reserved. */
236 PRINT_ERR("invalid queue operate type!\n");
237 return;
238 }
239
240 queueNode = &(queueCB->queueHandle[(queuePosition * (queueCB->queueSize))]);
241
242 if (OS_QUEUE_IS_READ(operateType)) {
243 if (memcpy_s(&msgDataSize, sizeof(UINT32), queueNode + queueCB->queueSize - sizeof(UINT32),
244 sizeof(UINT32)) != EOK) {
245 PRINT_ERR("get msgdatasize failed\n");
246 return;
247 }
248 msgDataSize = (*bufferSize < msgDataSize) ? *bufferSize : msgDataSize;
249 if (memcpy_s(bufferAddr, *bufferSize, queueNode, msgDataSize) != EOK) {
250 PRINT_ERR("copy message to buffer failed\n");
251 return;
252 }
253
254 *bufferSize = msgDataSize;
255 } else {
256 if (memcpy_s(queueNode, queueCB->queueSize, bufferAddr, *bufferSize) != EOK) {
257 PRINT_ERR("store message failed\n");
258 return;
259 }
260 if (memcpy_s(queueNode + queueCB->queueSize - sizeof(UINT32), sizeof(UINT32), bufferSize,
261 sizeof(UINT32)) != EOK) {
262 PRINT_ERR("store message size failed\n");
263 return;
264 }
265 }
266 }
267
OsQueueOperateParamCheck(const LosQueueCB * queueCB,UINT32 queueID,UINT32 operateType,const UINT32 * bufferSize)268 STATIC UINT32 OsQueueOperateParamCheck(const LosQueueCB *queueCB, UINT32 queueID,
269 UINT32 operateType, const UINT32 *bufferSize)
270 {
271 if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) {
272 return LOS_ERRNO_QUEUE_NOT_CREATE;
273 }
274
275 if (OS_QUEUE_IS_WRITE(operateType) && (*bufferSize > (queueCB->queueSize - sizeof(UINT32)))) {
276 return LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG;
277 }
278 return LOS_OK;
279 }
280
OsQueueOperate(UINT32 queueID,UINT32 operateType,VOID * bufferAddr,UINT32 * bufferSize,UINT32 timeout)281 UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize, UINT32 timeout)
282 {
283 UINT32 ret;
284 UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType);
285 UINT32 intSave;
286 OsHookCall(LOS_HOOK_TYPE_QUEUE_READ, (LosQueueCB *)GET_QUEUE_HANDLE(queueID), operateType, *bufferSize, timeout);
287
288 SCHEDULER_LOCK(intSave);
289 LosQueueCB *queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);
290 ret = OsQueueOperateParamCheck(queueCB, queueID, operateType, bufferSize);
291 if (ret != LOS_OK) {
292 goto QUEUE_END;
293 }
294
295 if (queueCB->readWriteableCnt[readWrite] == 0) {
296 if (timeout == LOS_NO_WAIT) {
297 ret = OS_QUEUE_IS_READ(operateType) ? LOS_ERRNO_QUEUE_ISEMPTY : LOS_ERRNO_QUEUE_ISFULL;
298 goto QUEUE_END;
299 }
300
301 if (!OsPreemptableInSched()) {
302 ret = LOS_ERRNO_QUEUE_PEND_IN_LOCK;
303 goto QUEUE_END;
304 }
305
306 LosTaskCB *runTask = OsCurrTaskGet();
307 OsTaskWaitSetPendMask(OS_TASK_WAIT_QUEUE, queueCB->queueID, timeout);
308 ret = runTask->ops->wait(runTask, &queueCB->readWriteList[readWrite], timeout);
309 if (ret == LOS_ERRNO_TSK_TIMEOUT) {
310 ret = LOS_ERRNO_QUEUE_TIMEOUT;
311 goto QUEUE_END;
312 }
313 } else {
314 queueCB->readWriteableCnt[readWrite]--;
315 }
316
317 OsQueueBufferOperate(queueCB, operateType, bufferAddr, bufferSize);
318
319 if (!LOS_ListEmpty(&queueCB->readWriteList[!readWrite])) {
320 LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[!readWrite]));
321 OsTaskWakeClearPendMask(resumedTask);
322 resumedTask->ops->wake(resumedTask);
323 SCHEDULER_UNLOCK(intSave);
324 LOS_MpSchedule(OS_MP_CPU_ALL);
325 LOS_Schedule();
326 return LOS_OK;
327 } else {
328 queueCB->readWriteableCnt[!readWrite]++;
329 }
330
331 QUEUE_END:
332 SCHEDULER_UNLOCK(intSave);
333 return ret;
334 }
335
LOS_QueueReadCopy(UINT32 queueID,VOID * bufferAddr,UINT32 * bufferSize,UINT32 timeout)336 LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueID,
337 VOID *bufferAddr,
338 UINT32 *bufferSize,
339 UINT32 timeout)
340 {
341 UINT32 ret;
342 UINT32 operateType;
343
344 ret = OsQueueReadParameterCheck(queueID, bufferAddr, bufferSize, timeout);
345 if (ret != LOS_OK) {
346 return ret;
347 }
348
349 operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD);
350 return OsQueueOperate(queueID, operateType, bufferAddr, bufferSize, timeout);
351 }
352
LOS_QueueWriteHeadCopy(UINT32 queueID,VOID * bufferAddr,UINT32 bufferSize,UINT32 timeout)353 LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID,
354 VOID *bufferAddr,
355 UINT32 bufferSize,
356 UINT32 timeout)
357 {
358 UINT32 ret;
359 UINT32 operateType;
360
361 ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);
362 if (ret != LOS_OK) {
363 return ret;
364 }
365
366 operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD);
367 return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);
368 }
369
LOS_QueueWriteCopy(UINT32 queueID,VOID * bufferAddr,UINT32 bufferSize,UINT32 timeout)370 LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueID,
371 VOID *bufferAddr,
372 UINT32 bufferSize,
373 UINT32 timeout)
374 {
375 UINT32 ret;
376 UINT32 operateType;
377
378 ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);
379 if (ret != LOS_OK) {
380 return ret;
381 }
382
383 operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL);
384 return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);
385 }
386
LOS_QueueRead(UINT32 queueID,VOID * bufferAddr,UINT32 bufferSize,UINT32 timeout)387 LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout)
388 {
389 return LOS_QueueReadCopy(queueID, bufferAddr, &bufferSize, timeout);
390 }
391
LOS_QueueWrite(UINT32 queueID,VOID * bufferAddr,UINT32 bufferSize,UINT32 timeout)392 LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout)
393 {
394 if (bufferAddr == NULL) {
395 return LOS_ERRNO_QUEUE_WRITE_PTR_NULL;
396 }
397 bufferSize = sizeof(CHAR *);
398 return LOS_QueueWriteCopy(queueID, &bufferAddr, bufferSize, timeout);
399 }
400
LOS_QueueWriteHead(UINT32 queueID,VOID * bufferAddr,UINT32 bufferSize,UINT32 timeout)401 LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueID,
402 VOID *bufferAddr,
403 UINT32 bufferSize,
404 UINT32 timeout)
405 {
406 if (bufferAddr == NULL) {
407 return LOS_ERRNO_QUEUE_WRITE_PTR_NULL;
408 }
409 bufferSize = sizeof(CHAR *);
410 return LOS_QueueWriteHeadCopy(queueID, &bufferAddr, bufferSize, timeout);
411 }
412
LOS_QueueDelete(UINT32 queueID)413 LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID)
414 {
415 LosQueueCB *queueCB = NULL;
416 UINT8 *queue = NULL;
417 UINT32 intSave;
418 UINT32 ret;
419
420 if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
421 return LOS_ERRNO_QUEUE_NOT_FOUND;
422 }
423
424 SCHEDULER_LOCK(intSave);
425 queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);
426 if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) {
427 ret = LOS_ERRNO_QUEUE_NOT_CREATE;
428 goto QUEUE_END;
429 }
430
431 if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_READ])) {
432 ret = LOS_ERRNO_QUEUE_IN_TSKUSE;
433 goto QUEUE_END;
434 }
435
436 if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_WRITE])) {
437 ret = LOS_ERRNO_QUEUE_IN_TSKUSE;
438 goto QUEUE_END;
439 }
440
441 if (!LOS_ListEmpty(&queueCB->memList)) {
442 ret = LOS_ERRNO_QUEUE_IN_TSKUSE;
443 goto QUEUE_END;
444 }
445
446 if ((queueCB->readWriteableCnt[OS_QUEUE_WRITE] + queueCB->readWriteableCnt[OS_QUEUE_READ]) !=
447 queueCB->queueLen) {
448 ret = LOS_ERRNO_QUEUE_IN_TSKWRITE;
449 goto QUEUE_END;
450 }
451
452 queue = queueCB->queueHandle;
453 queueCB->queueHandle = NULL;
454 queueCB->queueState = OS_QUEUE_UNUSED;
455 queueCB->queueID = SET_QUEUE_ID(GET_QUEUE_COUNT(queueCB->queueID) + 1, GET_QUEUE_INDEX(queueCB->queueID));
456 OsQueueDbgUpdateHook(queueCB->queueID, NULL);
457
458 LOS_ListTailInsert(&FREE_QUEUE_LIST, &queueCB->readWriteList[OS_QUEUE_WRITE]);
459 SCHEDULER_UNLOCK(intSave);
460 OsHookCall(LOS_HOOK_TYPE_QUEUE_DELETE, queueCB);
461 ret = LOS_MemFree(m_aucSysMem1, (VOID *)queue);
462 return ret;
463
464 QUEUE_END:
465 SCHEDULER_UNLOCK(intSave);
466 return ret;
467 }
468
LOS_QueueInfoGet(UINT32 queueID,QUEUE_INFO_S * queueInfo)469 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *queueInfo)
470 {
471 UINT32 intSave;
472 UINT32 ret = LOS_OK;
473 LosQueueCB *queueCB = NULL;
474 LosTaskCB *tskCB = NULL;
475
476 if (queueInfo == NULL) {
477 return LOS_ERRNO_QUEUE_PTR_NULL;
478 }
479
480 if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
481 return LOS_ERRNO_QUEUE_INVALID;
482 }
483
484 (VOID)memset_s((VOID *)queueInfo, sizeof(QUEUE_INFO_S), 0, sizeof(QUEUE_INFO_S));
485 SCHEDULER_LOCK(intSave);
486
487 queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);
488 if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) {
489 ret = LOS_ERRNO_QUEUE_NOT_CREATE;
490 goto QUEUE_END;
491 }
492
493 queueInfo->uwQueueID = queueID;
494 queueInfo->usQueueLen = queueCB->queueLen;
495 queueInfo->usQueueSize = queueCB->queueSize;
496 queueInfo->usQueueHead = queueCB->queueHead;
497 queueInfo->usQueueTail = queueCB->queueTail;
498 queueInfo->usReadableCnt = queueCB->readWriteableCnt[OS_QUEUE_READ];
499 queueInfo->usWritableCnt = queueCB->readWriteableCnt[OS_QUEUE_WRITE];
500
501 LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_READ], LosTaskCB, pendList) {
502 queueInfo->uwWaitReadTask |= 1ULL << tskCB->taskID;
503 }
504
505 LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_WRITE], LosTaskCB, pendList) {
506 queueInfo->uwWaitWriteTask |= 1ULL << tskCB->taskID;
507 }
508
509 LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->memList, LosTaskCB, pendList) {
510 queueInfo->uwWaitMemTask |= 1ULL << tskCB->taskID;
511 }
512
513 QUEUE_END:
514 SCHEDULER_UNLOCK(intSave);
515 return ret;
516 }
517
518 #endif /* LOSCFG_BASE_IPC_QUEUE */
519
520