• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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