• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
32 #include "los_queue.h"
33 #include "securec.h"
34 #include "los_config.h"
35 #include "los_debug.h"
36 #include "los_hook.h"
37 #include "los_interrupt.h"
38 #include "los_membox.h"
39 #include "los_memory.h"
40 #include "los_task.h"
41 #include "los_sched.h"
42 #include <stdint.h>
43 
44 
45 #if (LOSCFG_BASE_IPC_QUEUE == 1)
46 
47 LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL ;
48 LITE_OS_SEC_BSS LOS_DL_LIST g_freeQueueList;
49 
50 /**************************************************************************
51  Function    : OsQueueInit
52  Description : queue initial
53  Input       : None
54  Output      : None
55  Return      : LOS_OK on success or error code on failure
56 **************************************************************************/
OsQueueInit(VOID)57 LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID)
58 {
59     LosQueueCB *queueNode = NULL;
60     UINT16 index;
61 
62     if (LOSCFG_BASE_IPC_QUEUE_LIMIT == 0) {
63         return LOS_ERRNO_QUEUE_MAXNUM_ZERO;
64     }
65 
66     g_allQueue = (LosQueueCB *)LOS_MemAlloc(m_aucSysMem0, LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB));
67     if (g_allQueue == NULL) {
68         return LOS_ERRNO_QUEUE_NO_MEMORY;
69     }
70 
71     (VOID)memset_s(g_allQueue, LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB),
72                    0, LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB));
73 
74     LOS_ListInit(&g_freeQueueList);
75     for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) {
76         queueNode = ((LosQueueCB *)g_allQueue) + index;
77         queueNode->queueID = index;
78         LOS_ListTailInsert(&g_freeQueueList, &queueNode->readWriteList[OS_QUEUE_WRITE]);
79     }
80 
81     return LOS_OK;
82 }
83 
84 /*****************************************************************************
85  Function    : LOS_QueueCreate
86  Description : Create a queue
87  Input       : queueName  --- Queue name, less than 4 characters
88              : len        --- Queue length
89              : flags      --- Queue type, FIFO or PRIO
90              : maxMsgSize --- Maximum message size in byte
91  Output      : queueID    --- Queue ID
92  Return      : LOS_OK on success or error code on failure
93  *****************************************************************************/
LOS_QueueCreate(const CHAR * queueName,UINT16 len,UINT32 * queueID,UINT32 flags,UINT16 maxMsgSize)94 LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(const CHAR *queueName,
95                                              UINT16 len,
96                                              UINT32 *queueID,
97                                              UINT32 flags,
98                                              UINT16 maxMsgSize)
99 {
100     LosQueueCB *queueCB = NULL;
101     UINT32 intSave;
102     LOS_DL_LIST *unusedQueue = NULL;
103     UINT8 *queue = NULL;
104     UINT16 msgSize;
105 
106     (VOID)queueName;
107     (VOID)flags;
108 
109     if (queueID == NULL) {
110         return LOS_ERRNO_QUEUE_CREAT_PTR_NULL;
111     }
112 
113     if (maxMsgSize > (OS_NULL_SHORT - sizeof(UINT32))) {
114         return LOS_ERRNO_QUEUE_SIZE_TOO_BIG;
115     }
116 
117     if ((len == 0) || (maxMsgSize == 0)) {
118         return LOS_ERRNO_QUEUE_PARA_ISZERO;
119     }
120     msgSize = maxMsgSize + sizeof(UINT32);
121 
122     /* Memory allocation is time-consuming, to shorten the time of disable interrupt,
123        move the memory allocation to here. */
124     if ((UINT32_MAX / msgSize) < len) {
125         return LOS_ERRNO_QUEUE_SIZE_TOO_BIG;
126     }
127     queue = (UINT8 *)LOS_MemAlloc(m_aucSysMem0, (UINT32)len * msgSize);
128     if (queue == NULL) {
129         return LOS_ERRNO_QUEUE_CREATE_NO_MEMORY;
130     }
131 
132     intSave = LOS_IntLock();
133     if (LOS_ListEmpty(&g_freeQueueList)) {
134         LOS_IntRestore(intSave);
135         (VOID)LOS_MemFree(m_aucSysMem0, queue);
136         return LOS_ERRNO_QUEUE_CB_UNAVAILABLE;
137     }
138 
139     unusedQueue = LOS_DL_LIST_FIRST(&(g_freeQueueList));
140     LOS_ListDelete(unusedQueue);
141     queueCB = (GET_QUEUE_LIST(unusedQueue));
142     queueCB->queueLen = len;
143     queueCB->queueSize = msgSize;
144     queueCB->queue = queue;
145     queueCB->queueState = OS_QUEUE_INUSED;
146     queueCB->readWriteableCnt[OS_QUEUE_READ] = 0;
147     queueCB->readWriteableCnt[OS_QUEUE_WRITE] = len;
148     queueCB->queueHead = 0;
149     queueCB->queueTail = 0;
150     LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_READ]);
151     LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_WRITE]);
152     LOS_ListInit(&queueCB->memList);
153     LOS_IntRestore(intSave);
154 
155     *queueID = queueCB->queueID;
156 
157     OsHookCall(LOS_HOOK_TYPE_QUEUE_CREATE, queueCB);
158 
159     return LOS_OK;
160 }
161 
OsQueueReadParameterCheck(UINT32 queueID,VOID * bufferAddr,UINT32 * bufferSize,UINT32 timeOut)162 static INLINE LITE_OS_SEC_TEXT UINT32 OsQueueReadParameterCheck(UINT32 queueID, VOID *bufferAddr,
163                                                                 UINT32 *bufferSize, UINT32 timeOut)
164 {
165     if (queueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
166         return LOS_ERRNO_QUEUE_INVALID;
167     }
168     if ((bufferAddr == NULL) || (bufferSize == NULL)) {
169         return LOS_ERRNO_QUEUE_READ_PTR_NULL;
170     }
171 
172     if (*bufferSize == 0) {
173         return LOS_ERRNO_QUEUE_READSIZE_ISZERO;
174     }
175 
176     if (timeOut != LOS_NO_WAIT) {
177         if (OS_INT_ACTIVE) {
178             return LOS_ERRNO_QUEUE_READ_IN_INTERRUPT;
179         }
180     }
181     return LOS_OK;
182 }
183 
OsQueueWriteParameterCheck(UINT32 queueID,VOID * bufferAddr,UINT32 * bufferSize,UINT32 timeOut)184 static INLINE LITE_OS_SEC_TEXT UINT32 OsQueueWriteParameterCheck(UINT32 queueID, VOID *bufferAddr,
185                                                                  UINT32 *bufferSize, UINT32 timeOut)
186 {
187     if (queueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
188         return LOS_ERRNO_QUEUE_INVALID;
189     }
190 
191     if (bufferAddr == NULL) {
192         return LOS_ERRNO_QUEUE_WRITE_PTR_NULL;
193     }
194 
195     if (*bufferSize == 0) {
196         return LOS_ERRNO_QUEUE_WRITESIZE_ISZERO;
197     }
198 
199     if (timeOut != LOS_NO_WAIT) {
200         if (OS_INT_ACTIVE) {
201             return LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT;
202         }
203     }
204     return LOS_OK;
205 }
206 
OsQueueBufferOperate(LosQueueCB * queueCB,UINT32 operateType,VOID * bufferAddr,UINT32 * bufferSize)207 static INLINE VOID OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType,
208                                                                 VOID *bufferAddr, UINT32 *bufferSize)
209 {
210     UINT8 *queueNode = NULL;
211     UINT32 msgDataSize;
212     UINT16 queuePosition;
213     errno_t rc;
214 
215     /* get the queue position */
216     switch (OS_QUEUE_OPERATE_GET(operateType)) {
217         case OS_QUEUE_READ_HEAD:
218             queuePosition = queueCB->queueHead;
219             ((queueCB->queueHead + 1) == queueCB->queueLen) ? (queueCB->queueHead = 0) : (queueCB->queueHead++);
220             break;
221 
222         case OS_QUEUE_WRITE_HEAD:
223             (queueCB->queueHead == 0) ? (queueCB->queueHead = (queueCB->queueLen - 1)) : (--queueCB->queueHead);
224             queuePosition = queueCB->queueHead;
225             break;
226 
227         case OS_QUEUE_WRITE_TAIL:
228             queuePosition = queueCB->queueTail;
229             ((queueCB->queueTail + 1) == queueCB->queueLen) ? (queueCB->queueTail = 0) : (queueCB->queueTail++);
230             break;
231 
232         default:
233             PRINT_ERR("invalid queue operate type!\n");
234             return;
235     }
236 
237     queueNode = &(queueCB->queue[(queuePosition * (queueCB->queueSize))]);
238 
239     if (OS_QUEUE_IS_POINT(operateType)) {
240         if (OS_QUEUE_IS_READ(operateType)) {
241             *(UINTPTR *)bufferAddr = *(UINTPTR *)(VOID *)queueNode;
242         } else {
243             *(UINTPTR *)(VOID *)queueNode = *(UINTPTR *)bufferAddr;
244         }
245     } else {
246         if (OS_QUEUE_IS_READ(operateType)) {
247             msgDataSize = *((UINT32 *)(UINTPTR)((queueNode + queueCB->queueSize) - sizeof(UINT32)));
248             rc = memcpy_s((VOID *)bufferAddr, *bufferSize, (VOID *)queueNode, msgDataSize);
249             if (rc != EOK) {
250                 PRINT_ERR("%s[%d] memcpy failed, error type = %u\n", __FUNCTION__, __LINE__, rc);
251                 return;
252             }
253 
254             *bufferSize = msgDataSize;
255         } else {
256             *((UINT32 *)(UINTPTR)((queueNode + queueCB->queueSize) - sizeof(UINT32))) = *bufferSize;
257             rc = memcpy_s((VOID *)queueNode, queueCB->queueSize, (VOID *)bufferAddr, *bufferSize);
258             if (rc != EOK) {
259                 PRINT_ERR("%s[%d] memcpy failed, error type = %u\n", __FUNCTION__, __LINE__, rc);
260                 return;
261             }
262         }
263     }
264 }
265 
OsQueueOperateParamCheck(const LosQueueCB * queueCB,UINT32 operateType,const UINT32 * bufferSize)266 static INLINE UINT32 OsQueueOperateParamCheck(const LosQueueCB *queueCB, UINT32 operateType, const UINT32 *bufferSize)
267 {
268     if (queueCB->queueState == OS_QUEUE_UNUSED) {
269         return LOS_ERRNO_QUEUE_NOT_CREATE;
270     }
271 
272     if (OS_QUEUE_IS_READ(operateType) && (*bufferSize < (queueCB->queueSize - sizeof(UINT32)))) {
273         return LOS_ERRNO_QUEUE_READ_SIZE_TOO_SMALL;
274     } else if (OS_QUEUE_IS_WRITE(operateType) && (*bufferSize > (queueCB->queueSize - sizeof(UINT32)))) {
275         return LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG;
276     }
277 
278     if (*bufferSize >= SECUREC_MEM_MAX_LEN) {
279         return LOS_ERRNO_QUEUE_BUFFER_SIZE_TOO_BIG;
280     }
281 
282     return LOS_OK;
283 }
284 
OsQueueOperate(UINT32 queueID,UINT32 operateType,VOID * bufferAddr,UINT32 * bufferSize,UINT32 timeOut)285 UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize, UINT32 timeOut)
286 {
287     LosQueueCB *queueCB = NULL;
288     LosTaskCB *resumedTask = NULL;
289     UINT32 ret;
290     UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType);
291     UINT32 readWriteTmp = !readWrite;
292 
293     UINT32 intSave = LOS_IntLock();
294 
295     queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);
296     ret = OsQueueOperateParamCheck(queueCB, operateType, bufferSize);
297     if (ret != LOS_OK) {
298         goto QUEUE_END;
299     }
300 
301     if (queueCB->readWriteableCnt[readWrite] == 0) {
302         if (timeOut == LOS_NO_WAIT) {
303             ret = OS_QUEUE_IS_READ(operateType) ? LOS_ERRNO_QUEUE_ISEMPTY : LOS_ERRNO_QUEUE_ISFULL;
304             goto QUEUE_END;
305         }
306 
307         if (g_losTaskLock) {
308             ret = LOS_ERRNO_QUEUE_PEND_IN_LOCK;
309             goto QUEUE_END;
310         }
311 
312         LosTaskCB *runTsk = (LosTaskCB *)g_losTask.runTask;
313         OsSchedTaskWait(&queueCB->readWriteList[readWrite], timeOut);
314         LOS_IntRestore(intSave);
315         LOS_Schedule();
316 
317         intSave = LOS_IntLock();
318         if (runTsk->taskStatus & OS_TASK_STATUS_TIMEOUT) {
319             runTsk->taskStatus &= ~OS_TASK_STATUS_TIMEOUT;
320             ret = LOS_ERRNO_QUEUE_TIMEOUT;
321             goto QUEUE_END;
322         }
323     } else {
324         queueCB->readWriteableCnt[readWrite]--;
325     }
326 
327     OsQueueBufferOperate(queueCB, operateType, bufferAddr, bufferSize);
328 
329 
330     if (!LOS_ListEmpty(&queueCB->readWriteList[readWriteTmp])) {
331         resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[readWriteTmp]));
332         OsSchedTaskWake(resumedTask);
333         LOS_IntRestore(intSave);
334         LOS_Schedule();
335         return LOS_OK;
336     } else {
337         queueCB->readWriteableCnt[readWriteTmp]++;
338     }
339 
340 QUEUE_END:
341     LOS_IntRestore(intSave);
342     return ret;
343 }
344 
LOS_QueueReadCopy(UINT32 queueID,VOID * bufferAddr,UINT32 * bufferSize,UINT32 timeOut)345 LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueID,
346                                           VOID *bufferAddr,
347                                           UINT32 *bufferSize,
348                                           UINT32 timeOut)
349 {
350     UINT32 ret;
351     UINT32 operateType;
352 
353     ret = OsQueueReadParameterCheck(queueID, bufferAddr, bufferSize, timeOut);
354     if (ret != LOS_OK) {
355         return ret;
356     }
357 
358     operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD, OS_QUEUE_NOT_POINT);
359     return OsQueueOperate(queueID, operateType, bufferAddr, bufferSize, timeOut);
360 }
361 
LOS_QueueWriteHeadCopy(UINT32 queueID,VOID * bufferAddr,UINT32 bufferSize,UINT32 timeOut)362 LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID,
363                                                VOID *bufferAddr,
364                                                UINT32 bufferSize,
365                                                UINT32 timeOut)
366 {
367     UINT32 ret;
368     UINT32 operateType;
369 
370     ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeOut);
371     if (ret != LOS_OK) {
372         return ret;
373     }
374 
375     operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD, OS_QUEUE_NOT_POINT);
376     return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeOut);
377 }
378 
LOS_QueueWriteCopy(UINT32 queueID,VOID * bufferAddr,UINT32 bufferSize,UINT32 timeOut)379 LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueID,
380                                            VOID *bufferAddr,
381                                            UINT32 bufferSize,
382                                            UINT32 timeOut)
383 {
384     UINT32 ret;
385     UINT32 operateType;
386 
387     ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeOut);
388     if (ret != LOS_OK) {
389         return ret;
390     }
391 
392     operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL, OS_QUEUE_NOT_POINT);
393     return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeOut);
394 }
395 
LOS_QueueRead(UINT32 queueID,VOID * bufferAddr,UINT32 bufferSize,UINT32 timeOut)396 LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeOut)
397 {
398     UINT32 ret;
399     UINT32 operateType;
400 
401     ret = OsQueueReadParameterCheck(queueID, bufferAddr, &bufferSize, timeOut);
402     if (ret != LOS_OK) {
403         return ret;
404     }
405 
406     operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD, OS_QUEUE_POINT);
407 
408     OsHookCall(LOS_HOOK_TYPE_QUEUE_READ, (LosQueueCB *)GET_QUEUE_HANDLE(queueID), operateType, bufferSize, timeOut);
409 
410     return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeOut);
411 }
412 
LOS_QueueWrite(UINT32 queueID,VOID * bufferAddr,UINT32 bufferSize,UINT32 timeOut)413 LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeOut)
414 {
415     UINT32 ret;
416     UINT32 operateType;
417     UINT32 size = sizeof(UINT32 *);
418     (VOID)bufferSize;
419 
420     ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &size, timeOut);
421     if (ret != LOS_OK) {
422         return ret;
423     }
424 
425     operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL, OS_QUEUE_POINT);
426 
427     OsHookCall(LOS_HOOK_TYPE_QUEUE_WRITE, (LosQueueCB *)GET_QUEUE_HANDLE(queueID), operateType, size, timeOut);
428 
429     return OsQueueOperate(queueID, operateType, &bufferAddr, &size, timeOut);
430 }
431 
LOS_QueueWriteHead(UINT32 queueID,VOID * bufferAddr,UINT32 bufferSize,UINT32 timeOut)432 LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueID,
433                                            VOID *bufferAddr,
434                                            UINT32 bufferSize,
435                                            UINT32 timeOut)
436 {
437     UINT32 size = sizeof(UINT32 *);
438     (VOID)bufferSize;
439 
440     if (bufferAddr == NULL) {
441         return LOS_ERRNO_QUEUE_WRITE_PTR_NULL;
442     }
443 
444     return LOS_QueueWriteHeadCopy(queueID, &bufferAddr, size, timeOut);
445 }
446 
447 /*****************************************************************************
448  Function    : OsQueueMailAlloc
449  Description : Mail allocate memory
450  Input       : queueID   --- QueueID
451              : mailPool  --- MailPool
452              : timeOut   --- TimeOut
453  Output      : None
454  Return      : mem:pointer if success otherwise NULL
455  *****************************************************************************/
OsQueueMailAlloc(UINT32 queueID,VOID * mailPool,UINT32 timeOut)456 LITE_OS_SEC_TEXT VOID *OsQueueMailAlloc(UINT32 queueID, VOID *mailPool, UINT32 timeOut)
457 {
458     VOID *mem = (VOID *)NULL;
459     UINT32 intSave;
460     LosQueueCB *queueCB = (LosQueueCB *)NULL;
461     LosTaskCB *runTsk = (LosTaskCB *)NULL;
462 
463     if (queueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
464         return NULL;
465     }
466 
467     if (mailPool == NULL) {
468         return NULL;
469     }
470 
471     if (timeOut != LOS_NO_WAIT) {
472         if (OS_INT_ACTIVE) {
473             return NULL;
474         }
475     }
476 
477     intSave = LOS_IntLock();
478     queueCB = GET_QUEUE_HANDLE(queueID);
479     if (queueCB->queueState == OS_QUEUE_UNUSED) {
480         goto END;
481     }
482 
483     mem = LOS_MemboxAlloc(mailPool);
484     if (mem == NULL) {
485         if (timeOut == LOS_NO_WAIT) {
486             goto END;
487         }
488 
489         runTsk = (LosTaskCB *)g_losTask.runTask;
490         OsSchedTaskWait(&queueCB->memList, timeOut);
491         LOS_IntRestore(intSave);
492         LOS_Schedule();
493 
494         intSave = LOS_IntLock();
495         if (runTsk->taskStatus & OS_TASK_STATUS_TIMEOUT) {
496             runTsk->taskStatus &= (~OS_TASK_STATUS_TIMEOUT);
497             goto END;
498         } else {
499             /* When enters the current branch, means the current task already got an available membox,
500              * so the runTsk->msg can not be NULL.
501              */
502             mem = runTsk->msg;
503             runTsk->msg = NULL;
504         }
505     }
506 
507 END:
508     LOS_IntRestore(intSave);
509     return mem;
510 }
511 
512 /*****************************************************************************
513  Function    : OsQueueMailFree
514  Description : Mail free memory
515  Input       : queueID   --- QueueID
516              : mailPool  --- MailPool
517              : mailMem   --- MailMem
518  Output      : None
519  Return      : LOS_OK on success or error code on failure
520  *****************************************************************************/
OsQueueMailFree(UINT32 queueID,VOID * mailPool,VOID * mailMem)521 LITE_OS_SEC_TEXT UINT32 OsQueueMailFree(UINT32 queueID, VOID *mailPool, VOID *mailMem)
522 {
523     UINT32 intSave;
524     LosQueueCB *queueCB = (LosQueueCB *)NULL;
525     LosTaskCB *resumedTask = (LosTaskCB *)NULL;
526 
527     if (queueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
528         return LOS_ERRNO_QUEUE_MAIL_HANDLE_INVALID;
529     }
530 
531     if (mailPool == NULL) {
532         return LOS_ERRNO_QUEUE_MAIL_PTR_INVALID;
533     }
534 
535     intSave = LOS_IntLock();
536     queueCB = GET_QUEUE_HANDLE(queueID);
537     if (queueCB->queueState == OS_QUEUE_UNUSED) {
538         LOS_IntRestore(intSave);
539         return LOS_ERRNO_QUEUE_NOT_CREATE;
540     }
541 
542     if (!LOS_ListEmpty(&queueCB->memList)) {
543         resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->memList));
544         /* When enter this branch, it means the resumed task can
545          * get an available mailMem.
546          */
547         resumedTask->msg = mailMem;
548         OsSchedTaskWake(resumedTask);
549         LOS_IntRestore(intSave);
550         LOS_Schedule();
551     } else {
552         /* No task waiting for the mailMem, so free it. */
553         if (LOS_MemboxFree(mailPool, mailMem)) {
554             LOS_IntRestore(intSave);
555             return LOS_ERRNO_QUEUE_MAIL_FREE_ERROR;
556         }
557         LOS_IntRestore(intSave);
558     }
559 
560     return LOS_OK;
561 }
562 
563 /*****************************************************************************
564  Function    : LOS_QueueDelete
565  Description : Delete a queue
566  Input       : queueID   --- QueueID
567  Output      : None
568  Return      : LOS_OK on success or error code on failure
569  *****************************************************************************/
LOS_QueueDelete(UINT32 queueID)570 LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID)
571 {
572     LosQueueCB *queueCB = NULL;
573     UINT8 *queue = NULL;
574     UINT32 intSave;
575     UINT32 ret;
576 
577     if (queueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
578         return LOS_ERRNO_QUEUE_NOT_FOUND;
579     }
580 
581     intSave = LOS_IntLock();
582     queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);
583     if (queueCB->queueState == OS_QUEUE_UNUSED) {
584         ret = LOS_ERRNO_QUEUE_NOT_CREATE;
585         goto QUEUE_END;
586     }
587 
588     if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_READ])) {
589         ret = LOS_ERRNO_QUEUE_IN_TSKUSE;
590         goto QUEUE_END;
591     }
592 
593     if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_WRITE])) {
594         ret = LOS_ERRNO_QUEUE_IN_TSKUSE;
595         goto QUEUE_END;
596     }
597 
598     if (!LOS_ListEmpty(&queueCB->memList)) {
599         ret = LOS_ERRNO_QUEUE_IN_TSKUSE;
600         goto QUEUE_END;
601     }
602 
603     if ((queueCB->readWriteableCnt[OS_QUEUE_WRITE] + queueCB->readWriteableCnt[OS_QUEUE_READ]) !=
604         queueCB->queueLen) {
605         ret = LOS_ERRNO_QUEUE_IN_TSKWRITE;
606         goto QUEUE_END;
607     }
608 
609     queue = queueCB->queue;
610     queueCB->queue = (UINT8 *)NULL;
611     queueCB->queueState = OS_QUEUE_UNUSED;
612     LOS_ListAdd(&g_freeQueueList, &queueCB->readWriteList[OS_QUEUE_WRITE]);
613     LOS_IntRestore(intSave);
614 
615     OsHookCall(LOS_HOOK_TYPE_QUEUE_DELETE, queueCB);
616 
617     ret = LOS_MemFree(m_aucSysMem0, (VOID *)queue);
618     return ret;
619 
620 QUEUE_END:
621     LOS_IntRestore(intSave);
622     return ret;
623 }
624 
LOS_QueueInfoGet(UINT32 queueID,QUEUE_INFO_S * queueInfo)625 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *queueInfo)
626 {
627     UINT32 intSave;
628     UINT32 ret = LOS_OK;
629     LosQueueCB *queueCB = NULL;
630     LosTaskCB *tskCB = NULL;
631 
632     if (queueInfo == NULL) {
633         return LOS_ERRNO_QUEUE_PTR_NULL;
634     }
635 
636     if (queueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
637         return LOS_ERRNO_QUEUE_INVALID;
638     }
639 
640     (VOID)memset_s((VOID *)queueInfo, sizeof(QUEUE_INFO_S), 0, sizeof(QUEUE_INFO_S));
641     intSave = LOS_IntLock();
642 
643     queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);
644     if (queueCB->queueState == OS_QUEUE_UNUSED) {
645         ret = LOS_ERRNO_QUEUE_NOT_CREATE;
646         goto QUEUE_END;
647     }
648 
649     queueInfo->queueID = queueID;
650     queueInfo->queueLen = queueCB->queueLen;
651     queueInfo->queueSize = queueCB->queueSize;
652     queueInfo->queueHead = queueCB->queueHead;
653     queueInfo->queueTail = queueCB->queueTail;
654     queueInfo->readableCnt = queueCB->readWriteableCnt[OS_QUEUE_READ];
655     queueInfo->writableCnt = queueCB->readWriteableCnt[OS_QUEUE_WRITE];
656 
657     LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_READ], LosTaskCB, pendList) {
658         queueInfo->waitReadTask[OS_WAIT_TASK_ID_TO_ARRAY_IDX(tskCB->taskID)] |=
659             (1 << (tskCB->taskID & OS_WAIT_TASK_ARRAY_ELEMENT_MASK));
660     }
661 
662     LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_WRITE], LosTaskCB, pendList) {
663         queueInfo->waitWriteTask[OS_WAIT_TASK_ID_TO_ARRAY_IDX(tskCB->taskID)] |=
664             (1 << (tskCB->taskID & OS_WAIT_TASK_ARRAY_ELEMENT_MASK));
665     }
666 
667     LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->memList, LosTaskCB, pendList) {
668         queueInfo->waitMemTask[OS_WAIT_TASK_ID_TO_ARRAY_IDX(tskCB->taskID)] |=
669             (1 << (tskCB->taskID & OS_WAIT_TASK_ARRAY_ELEMENT_MASK));
670     }
671 
672 QUEUE_END:
673     LOS_IntRestore(intSave);
674     return ret;
675 }
676 
677 #endif /* (LOSCFG_BASE_IPC_QUEUE == 1) */
678 
679