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