fifo 类型结构体 c语言,精简通用环形fifo

/***************************************************************************

*   Copyright(C)2009-2012 by Gorgon Meducer *

*                                                                         *

*   This program is free software; you can redistribute it and/or modify  *

*   it under the terms of the GNU Lesser General Public License as        *

*   published by the Free Software Foundation; either version 2 of the    *

*   License, or (at your option) any later version.                       *

*                                                                         *

*   This program is distributed in the hope that it will be useful,       *

*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *

*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *

*   GNU General Public License for more details.                          *

*                                                                         *

*   You should have received a copy of the GNU Lesser General Public      *

*   License along with this program; if not, write to the                 *

*   Free Software Foundation, Inc.,                                       *

*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *

***************************************************************************/

#ifndef _USE_TEMPLATE_QUEUE_H_

#define _USE_TEMPLATE_QUEUE_H_

/*============================ INCLUDES ======================================*/

/*============================ MACROS ========================================*/

#define END_DEF_QUEUE

#define END_DEF_QUEUE_U8

#define END_DEF_QUEUE_U16

#define END_DEF_QUEUE_U32

#define END_DEF_SAFE_QUEUE

#define END_DEF_SAFE_QUEUE_U8

#define END_DEF_SAFE_QUEUE_U16

#define END_DEF_SAFE_QUEUE_U32

/*============================ MACROFIED FUNCTIONS ===========================*/

#define NONE_ATOM_ACCESS(__CODE)        {__CODE;}

#define QUEUE_MUTEX(__NAME, __QUEUE)                                        \

__NAME##_queue_mutex(__QUEUE)

#define QUEUE_INIT(__NAME, __QUEUE, __BUFFER, __SIZE)                       \

__NAME##_queue_init((__QUEUE), (__BUFFER), (__SIZE))

#define DEQUEUE(__NAME, __QUEUE, __ADDR)                                    \

__NAME##_dequeue((__QUEUE),(__ADDR))

#define ENQUEUE(__NAME, __QUEUE, __VALUE)                                   \

__NAME##_enqueue((__QUEUE), (__VALUE))

#define PEEK_QUEUE(__NAME, __QUEUE, __ADDR)                                 \

__NAME##_queue_peek((__QUEUE),(__ADDR))

#define QUEUE(__NAME)   __NAME##_queue_t

#define DEF_QUEUE_EX(__NAME, __TYPE, __PTR_TYPE, __MUTEX_TYPE, __ATOM_ACCESS)  \

DEF_CLASS                                                                   \

__TYPE          *ptBuffer;                                              \

__PTR_TYPE      tSize;                                                  \

__PTR_TYPE      tHead;                                                  \

__PTR_TYPE      tTail;                                                  \

__PTR_TYPE      tCounter;                                               \

__MUTEX_TYPE    tMutex;                                                 \

END_DEF_CLASS(__NAME##_queue_t)                                             \

\

__MUTEX_TYPE *__NAME##_queue_mutex(__NAME##_queue_t *ptQueue)               \

{                                                                           \

CLASS(__NAME##_queue_t) *ptQ = (CLASS(__NAME##_queue_t) *)ptQueue;      \

if ( NULL == ptQueue)  {                                                \

return NULL;                                                        \

}                                                                       \

return &(ptQ->tMutex);                                                  \

}                                                                           \

\

bool __NAME##_queue_init(__NAME##_queue_t *ptQueue, __TYPE *ptBuffer, __PTR_TYPE tSize) \

{                                                                           \

CLASS(__NAME##_queue_t) *ptQ = (CLASS(__NAME##_queue_t) *)ptQueue;      \

if (NULL == ptQueue || NULL == ptBuffer || 0 == tSize) {                \

return false;                                                       \

}                                                                       \

\

ptQ->ptBuffer = ptBuffer;                                               \

ptQ->tSize = tSize;                                                     \

ptQ->tHead = 0;                                                         \

ptQ->tTail = 0;                                                         \

ptQ->tCounter = 0;                                                      \

\

return true;                                                            \

}                                                                           \

\

bool __NAME##_enqueue(__NAME##_queue_t *ptQueue, __TYPE tObj)               \

{                                                                           \

bool bResult = false;                                                   \

CLASS(__NAME##_queue_t) *ptQ = (CLASS(__NAME##_queue_t) *)ptQueue;      \

if (NULL == ptQ) {                                                      \

return false;                                                       \

}                                                                       \

\

__ATOM_ACCESS(                                                          \

do {                                                                \

if ((ptQ->tHead == ptQ->tTail) && (0 != ptQ->tCounter)) {       \

break;                                                      \

}                                                               \

\

ptQ->ptBuffer[ptQ->tTail++] = tObj;                             \

if (ptQ->tTail >= ptQ->tSize) {                                 \

ptQ->tTail = 0;                                             \

}                                                               \

ptQ->tCounter++;                                                \

bResult = true;                                                 \

} while (false);                                                    \

)                                                                       \

\

return bResult;                                                         \

}                                                                           \

\

bool __NAME##_queue_peek(__NAME##_queue_t *ptQueue, __TYPE *ptObj)          \

{                                                                           \

bool bResult = false;                                                   \

CLASS(__NAME##_queue_t) *ptQ = (CLASS(__NAME##_queue_t) *)ptQueue;      \

if (NULL == ptQ) {                                                      \

return false;                                                       \

}                                                                       \

\

__ATOM_ACCESS(                                                          \

do {                                                                \

if ((ptQ->tHead == ptQ->tTail) && (!ptQ->tCounter)) {           \

break;                                                      \

}                                                               \

if (NULL != ptObj) {                                            \

*ptObj = ptQ->ptBuffer[ptQ->tHead];                         \

}                                                               \

bResult = true;                                                 \

} while (false);                                                    \

)                                                                       \

\

return bResult;                                                         \

}                                                                           \

bool __NAME##_dequeue(__NAME##_queue_t *ptQueue, __TYPE *ptObj)             \

{                                                                           \

bool bResult = false;                                                   \

CLASS(__NAME##_queue_t) *ptQ = (CLASS(__NAME##_queue_t) *)ptQueue;      \

if (NULL == ptQ) {                                                      \

return false;                                                       \

}                                                                       \

\

__ATOM_ACCESS(                                                          \

do {                                                                \

if ((ptQ->tHead == ptQ->tTail) && (!ptQ->tCounter)) {           \

break;                                                      \

}                                                               \

if (NULL != ptObj) {                                            \

*ptObj = ptQ->ptBuffer[ptQ->tHead];                         \

}                                                               \

ptQ->tHead++;                                                   \

if (ptQ->tHead >= ptQ->tSize) {                                 \

ptQ->tHead = 0;                                             \

}                                                               \

ptQ->tCounter--;                                                \

bResult = true;                                                 \

} while (false);                                                    \

)                                                                       \

\

return bResult;                                                         \

}                                                                           \

#define DEF_SAFE_QUEUE(__NAME, __TYPE, __PTR_TYPE, __MUTEX_TYPE)            \

DEF_QUEUE_EX(__NAME, __TYPE, __PTR_TYPE, __MUTEX_TYPE, SAFE_ATOM_CODE)

#define DEF_SAFE_QUEUE_U8(__NAME, __PTR_TYPE,__MUTEX_TYPE)                  \

DEF_SAFE_QUEUE(__NAME, uint8_t, __PTR_TYPE, __MUTEX_TYPE)

#define DEF_SAFE_QUEUE_U16(__NAME, __PTR_TYPE, __MUTEX_TYPE)                \

DEF_SAFE_QUEUE(__NAME, uint16_t, __PTR_TYPE, __MUTEX_TYPE)

#define DEF_SAFE_QUEUE_U32(__NAME, __PTR_TYPE, __MUTEX_TYPE)                \

DEF_SAFE_QUEUE(__NAME, uint32_t __PTR_TYPE, __MUTEX_TYPE)

#define DEF_QUEUE(__NAME, __TYPE, __PTR_TYPE, __MUTEX_TYPE)                 \

DEF_QUEUE_EX(__NAME, __TYPE, __PTR_TYPE, __MUTEX_TYPE, NONE_ATOM_ACCESS)

#define DEF_QUEUE_U8(__NAME, __PTR_TYPE,__MUTEX_TYPE)                       \

DEF_QUEUE(__NAME, uint8_t, __PTR_TYPE, __MUTEX_TYPE)

#define DEF_QUEUE_U16(__NAME, __PTR_TYPE, __MUTEX_TYPE)                     \

DEF_QUEUE(__NAME, uint16_t, __PTR_TYPE, __MUTEX_TYPE)

#define DEF_QUEUE_U32(__NAME, __PTR_TYPE, __MUTEX_TYPE)                     \

DEF_QUEUE(__NAME, uint32_t __PTR_TYPE, __MUTEX_TYPE)

/*============================ TYPES =========================================*/

/*============================ GLOBAL VARIABLES ==============================*/

/*============================ LOCAL VARIABLES ===============================*/

/*============================ PROTOTYPES ====================================*/

/*============================ IMPLEMENTATION ================================*/

#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 环形FIFO(First In First Out)是一种队列数据结构,它具有环形的特点,可以循环利用存储空间。在C语言中,我们可以使用数组来实现环形FIFO。 首先,我们需要定义一个固定大小的数组作为环形FIFO的缓冲区,并定义两个指针front和rear来分别指向队首和队尾元素。同时,我们还需要定义一个变量count来记录当前队列中的元素数量。 在初始化环形FIFO时,我们将front和rear都设置为0,count设置为0。 入队操作时,我们首先判断count的值是否已达到缓冲区的最大容量。若已满,则无法入队,否则我们将要入队的元素存储到rear指向的位置上,并将rear指针向后移动一位。同时,我们还需要更新count的值。 出队操作时,我们首先判断count的值是否为0,若为0,则队列为空,无法出队。否则,我们将front指向的元素取出,并将front指针向后移动一位。同时,我们还需要更新count的值。 需要注意的是,在环形FIFO中,当rear指针到达数组的末尾时,若后续还有空闲位置,我们需要将rear指针移到数组的起始位置。同样,当front指针到达数组的末尾时,若后续还有元素,我们需要将front指针移到数组的起始位置。 以上就是使用C语言实现环形FIFO的基本操作。除此之外,我们还可以添加其他的功能,如判断队列是否为空、是否已满,以及查看队列中的元素等。通过合理的设计和利用循环的特性,环形FIFO可以高效地实现队列的功能。 ### 回答2: 环形FIFO(First-In-First-Out,先进先出)是一种常见的数据结构,通常用于解决生产者-消费者问题。它类似于一个环形的队列,新的数据项会被插入到队列的尾部,而队列头部的数据项会被移除。 通过C语言可以很方便地实现环形FIFO。我们可以使用一个固定大小的数组作为环形FIFO的缓冲区,并使用两个指针来标记队列的头部和尾部。 首先,我们需要定义环形FIFO的数据结构。可以包含一个数组,两个整型变量分别代表队列的头部和尾部指针,以及一个计数器变量用于记录队列中的元素个数。 接下来,我们需要实现一些基本操作。例如,创建一个空的环形FIFO、向队列中插入新的数据项、从队列中删除数据项、获取队列头部的数据项等等。 在向队列中插入数据项时,我们需要先判断队列是否已满。如果队列未满,则将数据插入到尾部,并更新尾部指针和计数器;如果队列已满,则无法插入新的数据项。 在删除数据项时,我们需要先判断队列是否为空。如果队列非空,则将头部的数据项删除,并更新头部指针和计数器;如果队列为空,则无法删除数据项。 通过以上的操作,我们可以实现一个简单的环形FIFO。在多线程环境下,我们需要加锁来保证队列的线程安全性。 总结起来,通过C语言可以很方便地实现环形FIFO数据结构。我们可以使用固定大小的数组作为缓冲区,并通过头尾指针和计数器来操作队列中的元素。环形FIFO可以用于解决生产者-消费者问题,在多线程环境下需要加锁来保证线程安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值