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