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); | ||
|  | } |