先进先出队列 FIFO

fifo.h

---------------------------------------------------------------------------------------------------------

#ifndef FIFO_H
#define FIFO_H

#include <pthread.h>

#ifdef __cplusplus
extern "C" {
#endif

#pragma pack(1)

typedef struct{
    char* buffer;
    int buffer_size;
    int count;
    int write_ptr;
    int read_ptr;
    pthread_mutex_t mutex;
}tFifo,*pFifo;

#pragma pack()

int fifo_init(pFifo pfifo);
void fifo_uninit(pFifo pfifo);

int fifo_into(pFifo pfifo,char* buffer,int buffer_size);

char *fifo_get(pFifo pfifo,int* out_len);
int fifo_remove(pFifo pfifo);

#ifdef __cplusplus
}
#endif

#endif

 

fifo.c

---------------------------------------------------------------------------------------------------------

 

#include "fifo.h"
#include "../debug/debug.h"

#if 0
#define _debug_fifo
#endif

#ifdef _debug_fifo
#define debug_fifo(fmt,...) debug(fmt,##__VA_ARGS__)
#else
#define debug_fifo(fmt,...)
#endif

#if 1
#define FIFO_USE_MUTEX
#endif

#define FIFO_NODE_INVALID               0xFF
#define FIFO_NODE_VALID                 0x00

#pragma pack(1)

typedef struct{
    char flag;
    int len;
}tNodeHead,*pNodeHead;

#pragma pack()

int fifo_init(pFifo pfifo)
{
    debug_fifo("/n");

    if(pfifo==NULL){
        return -1;
    }

    pfifo->count     = 0;
    pfifo->read_ptr  = 0;
    pfifo->write_ptr = 0;

    return 0;
}

void fifo_uninit(pFifo pfifo)
{
    debug_fifo("/n");
    return;
}

static int fifo_check_spare(pFifo pfifo,int need_len)
{
    debug_fifo("/n");

    int spare = 0;
    if(pfifo->write_ptr >= pfifo->read_ptr)
    {
        spare = pfifo->buffer_size - pfifo->write_ptr;
        if(need_len > spare)
        {
            if(pfifo->read_ptr > need_len){
                if(spare>0){
                    pfifo->buffer[pfifo->write_ptr] = FIFO_NODE_INVALID;
                }
                spare = pfifo->read_ptr;
            }else
                spare = -1;
        }
     }else
     {
         spare = pfifo->read_ptr - pfifo->write_ptr;
     }

    if( spare == 0 )
        return pfifo->buffer_size;
    else if( spare >= need_len )
        return spare;
    return -1;
}

#define check_write_ptr(){/
    if(pfifo->write_ptr>=pfifo->buffer_size || pfifo->buffer[pfifo->write_ptr]==FIFO_NODE_INVALID){/
            debug_fifo("reset write_ptr=0/n");/
            pfifo->write_ptr = 0;/
    }/
}

int fifo_into(pFifo pfifo,char* buffer,int buffer_size)
{
    debug_fifo("/n");

    int retval = -1;

#ifdef FIFO_USE_MUTEX
    pthread_mutex_lock(&(pfifo->mutex));
#endif

    if(buffer==0||buffer_size<=0){
        debug_warning("buffer is null/n");
        goto error;
    }

    debug_fifo("begin read_ptr=%d,write_ptr=%d/n",pfifo->read_ptr,pfifo->write_ptr);

    int node_head_len = sizeof(tNodeHead);
    int need_size = node_head_len + buffer_size;

    int spare=fifo_check_spare(pfifo,need_size);
    debug_fifo("spare=%d/n",spare);

    if(spare < 0)
    {
        debug_error("task buffer so busy,spare=%d,node head len=%d,need_len=%d/n",spare,node_head_len,need_size);
        goto error;
    }

    check_write_ptr();

    pNodeHead pHead = pfifo->buffer + pfifo->write_ptr;

    pHead->flag = FIFO_NODE_VALID;
    pHead->len  = need_size;

    char* pdata = ((char*)pHead) + node_head_len;

    memcpy(pdata,buffer,buffer_size);
    pfifo->write_ptr += need_size;

    debug_fifo("end read_ptr=%d,write_ptr=%d/n",pfifo->read_ptr,pfifo->write_ptr);

    pfifo->count++;

    retval=pfifo->count;

    debug_fifo("task post ok,read_ptr=%d,write_ptr=%d,write len=%d,count=%d/n",pfifo->read_ptr,pfifo->write_ptr,need_size,pfifo->count);

#if 0
    int i;
    debug("data=");
    for(i=0;i<need_size+0x10;i++)
    {
        debugf("0x%02x ",((char*)pHead)[i]);
        if(i==need_size-1)
            debugf(" ~ ");
    }
    debugf("/n");
#endif

error:
#ifdef FIFO_USE_MUTEX
    pthread_mutex_unlock(&(pfifo->mutex));
#endif
    return retval;
}

static int fifo_is_empty(pFifo pfifo)
{
    debug_fifo("/n");
    int retval=0;
    if(pfifo->write_ptr==pfifo->read_ptr)
        retval=1;
    return retval;
}

#define check_read_ptr(){/
    if(pfifo->read_ptr>=pfifo->buffer_size || pfifo->buffer[pfifo->read_ptr]==FIFO_NODE_INVALID){/
            debug_fifo("reset read_ptr=0/n");/
            pfifo->read_ptr = 0;/
    }/
}

char* fifo_get(pFifo pfifo,int* out_len)
{
    debug_fifo("/n");

#ifdef FIFO_USE_MUTEX
    pthread_mutex_lock(&(pfifo->mutex));
#endif

    char* retval = NULL;

    if(!fifo_is_empty(pfifo))
    {
        check_read_ptr();

        int node_head_len = sizeof(tNodeHead);
        pNodeHead pHead = (pNodeHead)(pfifo->buffer + pfifo->read_ptr);
        retval = ((char*)pHead) + node_head_len;

        int outlen = pHead->len - node_head_len;

        if(out_len!=NULL){
            *out_len = outlen;
        }
#if 1
        debug_fifo("task get ok,read_ptr=%d,write_ptr=%d,read len=%d,out len=%d,count=%d/n",pfifo->read_ptr,pfifo->write_ptr,pHead->len,outlen,pfifo->count);
#endif
    }

#ifdef FIFO_USE_MUTEX
    pthread_mutex_unlock(&(pfifo->mutex));
#endif
    return retval;
}

int fifo_remove(pFifo pfifo)
{
    debug_fifo("/n");
    int retval = -1;

#ifdef FIFO_USE_MUTEX
    pthread_mutex_lock(&(pfifo->mutex));
#endif

    if(!fifo_is_empty(pfifo))
    {
        debug_fifo("task remove begin,read_ptr=%d,write_ptr=%d,count=%d/n",pfifo->read_ptr,pfifo->write_ptr,pfifo->count);

        check_read_ptr();

        pNodeHead pHead = (pNodeHead)(pfifo->buffer + pfifo->read_ptr);

        int node_size = pHead->len;
        pfifo->read_ptr += node_size;

        pfifo->count--;

        retval = pfifo->count;
#if 1
        debug_fifo("task remove ok,read_ptr=%d,write_ptr=%d,remove len=%d,count=%d/n",pfifo->read_ptr,pfifo->write_ptr,node_size,pfifo->count);
#endif
    }

#ifdef FIFO_USE_MUTEX
    pthread_mutex_unlock(&(pfifo->mutex));
#endif
    return retval;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值