125 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /****************************************************************************
 | |
| 
 | |
| Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
 | |
| 
 | |
| This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
 | |
| be copied by any method or incorporated into another program without
 | |
| the express written consent of Aerospace C.Power. This Information or any portion
 | |
| thereof remains the property of Aerospace C.Power. The Information contained herein
 | |
| is believed to be accurate and Aerospace C.Power assumes no responsibility or
 | |
| liability for its use in any way and conveys no license or title under
 | |
| any patent or copyright and makes no representation or warranty that this
 | |
| Information is free from patent or copyright infringement.
 | |
| 
 | |
| ****************************************************************************/
 | |
| 
 | |
| /* os shim includes */
 | |
| #include "os_types.h"
 | |
| #include "os_lock.h"
 | |
| 
 | |
| /* common includes */
 | |
| #include "iot_errno.h"
 | |
| #include "iot_module.h"
 | |
| #include "iot_queue.h"
 | |
| 
 | |
| uint32_t iot_msg_queue_init(iot_msg_queue_t *queue)
 | |
| {
 | |
|     uint32_t ret = 0;
 | |
| 
 | |
|     queue->lock = os_create_mutex(IOT_QUEUE_MID);
 | |
|     if (queue->lock == NULL) {
 | |
|         ret = ERR_NOMEM;
 | |
|         goto out;
 | |
|     }
 | |
| 
 | |
|     queue->cnt = 0;
 | |
|     queue->head = NULL;
 | |
|     queue->tail = NULL;
 | |
| 
 | |
| out:
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| void iot_msg_queue_deinit(iot_msg_queue_t *queue)
 | |
| {
 | |
|     IOT_ASSERT(queue->head == NULL && queue->tail == NULL);
 | |
|     IOT_ASSERT(queue->cnt == 0);
 | |
|     IOT_ASSERT(queue->lock);
 | |
| 
 | |
|     os_delete_mutex(queue->lock);
 | |
|     queue->lock = NULL;
 | |
| }
 | |
| 
 | |
| void iot_msg_queue_put(iot_msg_queue_t *queue, iot_msg_entry_t *msg)
 | |
| {
 | |
|     IOT_ASSERT(queue->lock);
 | |
| 
 | |
|     os_acquire_mutex(queue->lock);
 | |
|     IOT_ASSERT(msg->next == NULL);
 | |
|     if (queue->head == NULL) {
 | |
|         IOT_ASSERT(queue->tail == NULL);
 | |
|         queue->head = msg;
 | |
|     }
 | |
|     if (queue->tail) {
 | |
|         IOT_ASSERT(queue->head);
 | |
|         queue->tail->next = msg;
 | |
|     }
 | |
|     queue->tail = msg;
 | |
|     queue->cnt++;
 | |
|     os_release_mutex(queue->lock);
 | |
| }
 | |
| 
 | |
| iot_msg_entry_t *iot_msg_queue_get(iot_msg_queue_t *queue)
 | |
| {
 | |
|     iot_msg_entry_t *entry = NULL;
 | |
| 
 | |
|     IOT_ASSERT(queue->lock);
 | |
| 
 | |
|     os_acquire_mutex(queue->lock);
 | |
|     if (queue->head) {
 | |
|         IOT_ASSERT(queue->tail);
 | |
|         queue->cnt--;
 | |
|         entry = queue->head;
 | |
|         if (queue->head == queue->tail) {
 | |
|             queue->head = NULL;
 | |
|             queue->tail = NULL;
 | |
|         } else {
 | |
|             queue->head = queue->head->next;
 | |
|         }
 | |
|         entry->next = NULL;
 | |
|     } else {
 | |
|         IOT_ASSERT(queue->tail == NULL);
 | |
|     }
 | |
|     os_release_mutex(queue->lock);
 | |
| 
 | |
|     return entry;
 | |
| }
 | |
| 
 | |
| void iot_msg_queue_loop(iot_msg_queue_t *queue, iot_msg_queue_loop_func_t func,
 | |
|     void *param)
 | |
| {
 | |
|     iot_msg_entry_t *prev = NULL, *curr = NULL, *next = NULL;
 | |
| 
 | |
|     IOT_ASSERT(queue->lock);
 | |
| 
 | |
|     os_acquire_mutex(queue->lock);
 | |
|     curr = queue->head;
 | |
|     while (curr) {
 | |
|         next = curr->next;
 | |
|         if (func(curr, param)) {
 | |
|             queue->cnt--;
 | |
|             if (prev) {
 | |
|                 prev->next = next;
 | |
|             } else {
 | |
|                 queue->head = next;
 | |
|             }
 | |
|             if (queue->tail == curr) {
 | |
|                 queue->tail = prev;
 | |
|             }
 | |
|         } else {
 | |
|             prev = curr;
 | |
|         }
 | |
|         curr = next;
 | |
|     }
 | |
|     os_release_mutex(queue->lock);
 | |
| } |