先进先出队列 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;
}
---------------------------------------------------------------------------------------------------------
#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;
}
相关文章推荐
- 队列Queue FIFO先进先出 栈Stack FILO先进后出
- Java ArrayDeque、PriorityQueue 先进先出队列(FIFO)
- spring+mybatsi FIFO(先进先出)队列,解决并发问题
- 队列(FIFO)先进先出
- 队列(Queue)——先进先出(FIFO)的数据结构(Data Structures)
- 【JAVA数据结构】先进先出队列
- 消息队列是先进先出
- 笔记:进程间通信——消息传递(管道、FIFO、posix消息队列)
- 2.2 先进先出结构:队列
- BlockingQueue:队列(FIFO)
- JS实现队列效果,先进先出
- 单片机的FIFO(先入先出)循环队列实现
- 【JAVA并发编程实战】12、使用condition实现多线程下的有界缓存先进先出队列
- android开发常用的缓存策略详解(2)- 先进先出(FIFO)置换算法
- 阻塞双端消息队列 BlockingDeque(先进先出的原则管理)
- JS优先队列排序。出队时,先找出优先级最高的元素,再按照先进先出出队。
- 挺有意思的,队列,先进先出,排队进行!
- 分支限界法解决装载问题之FIFO队列方式的总结
- 使用堆栈(Stack)模拟实现队列(FIFO)
- 第六章堆排序之“优先级队列实现先进先出队列和栈”(练习6.5-6)