/*****************************************************************************/ /** * Description: A simple circular FIFO bounded queue * * Author: Fan Hao * Date: 2023-02-23 10:29 * LastEditors: Fan Hao * LastEditTime: 2023-02-23 13:18 * Revisions: Rev 0.0 * History: * [2023-02-23]: Initial Version. * * Copyright(c) 2023 Beijing Institute of Technology. * Lab of Communication and Networking * NOTE: Forked from https://github.com/chrismerck/rpa_queue.git * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ #include "circ_queue.h" #include "../common.h" #include #include #include inline bool isCircQueueFull(CIRC_QUEUE *queue) { ASSERT(queue != NULL); return ((queue)->nelts == (queue)->bounds); } inline bool isCircQueueEmpty(CIRC_QUEUE *queue) { ASSERT(queue != NULL); return ((queue)->nelts == 0); } void CircQueueFree(CIRC_QUEUE *queue) { ASSERT(queue != NULL); if (queue->data) free(queue->data); free(queue); } /** * Initialize the CIRC_QUEUE. */ bool CircQueueCreate(CIRC_QUEUE **q, uint32_t queueCapacity) { ASSERT(q != NULL); CIRC_QUEUE *queue; queue = malloc(sizeof(CIRC_QUEUE)); if (!queue) { return false; } *q = queue; memset(queue, 0, sizeof(CIRC_QUEUE)); /* Set all the data in the queue to NULL */ queue->data = malloc(queueCapacity * sizeof(void *)); if (queue->data == NULL) { goto error; } queue->bounds = queueCapacity; queue->nelts = 0; queue->in = 0; queue->out = 0; return true; error: free(queue); return false; } /** * Push new data onto the queue. */ bool CircQueuePush(CIRC_QUEUE *queue, void *data) { ASSERT(queue != NULL); if (isCircQueueFull(queue)) { return false; } queue->data[queue->in] = data; queue->in++; if (queue->in >= queue->bounds) { queue->in -= queue->bounds; } queue->nelts++; return true; } /** * Return current number of element in queue. */ inline uint32_t CircQueueSize(CIRC_QUEUE *queue) { return queue->nelts; } /** * Retrieves the next item from the queue. */ bool CircQueuePop(CIRC_QUEUE *queue, void **data) { ASSERT(queue != NULL); if (isCircQueueEmpty(queue)) { return false; } *data = queue->data[queue->out]; queue->nelts--; queue->out++; if (queue->out >= queue->bounds) { queue->out -= queue->bounds; } return true; }