您的位置:首页 > 其它

先进先出队列 FIFO

2011-06-24 01:16 295 查看
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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: