环形队列数据的循环读写

来源:互联网 发布:net域名一年多少钱 编辑:程序博客网 时间:2024/06/08 17:00

在内存中建立一个环形队列的数据结构,此数据结构遵循先进先出的原则,它是用于对交通灯驱动程序的上半部和下半部之间缓冲数据,其中ring_buf_read()函数用于对环形队列进行读取数据。(本算法来自蒋静《操作系统原理。技术与编程》一书P392页)

 

#define R_SIGNATURE 0x860510
typedef struct{
 long signature;
 int *head;
 int *tail;
 int *end;
 int *begin;
 int buffer[64];
}ring_buf;  //定义一个环形队列数据结构

 


#include <unistd.h>
#include <linux/kernel.h>
#include "ring.h"
int  tag=0;
int * psudo_head=NULL;

 

void ring_buf_init(ring_buf *round)
{
        round->signature=R_SIGNATURE;
        round->head=round->buffer;
        round->tail=round->buffer;
        round->begin=round->buffer;
        round->end=&round->buffer[sizeof(round->buffer)-1];
}

/**   read the user_defined value from the ring_buffer,
 **    if no value available 0 is returned, on error -1 is
 **    returned, on success 1 is returned **/

int ring_buf_read(ring_buf *round,int *val)
{
        int* tmp=round->tail;//每次调用该函数时都会将round->tail指针的值赋给tmp,因为round->tail始终指向环形队列中未读数据的地址,这是下面round->tail=tmp语句来实现的

        if(round->signature !=R_SIGNATURE){
                printk("ring_buf_read:signature fake/n");
                return(-1);
        }

        if((tmp<round->begin)||(tmp>round->end)){
                printk("ring_buf_read:tail bad/n");
                return(-1);
        }

        if(tmp==round->head){
              return(0);
        }

        *val=*tmp++;//将*tmp指向的值赋给val,实现数据的读出操作

        if(tmp>round->end)
                tmp=round->begin;
        round->tail=tmp;//保证round->tail始终指向环形队列中未读数据的地址,从而实现循环读取
        if(tag){
                round->head=psudo_head;
                tag=0;
        }

        return(1);
}

 

 

int ring_buf_write(ring_buf *round,int val)
{
        int* tmp=round->head;

        if(round->signature !=R_SIGNATURE){
                         printk("ring_buf_write:signature fake/n");
                return(-1);
        }
        if((tmp<round->begin)||(tmp>round->end)){
                printk("ring_buf_write:head bad/n");
                return(-1);
        }

        if(tag)
                return 0;
        (*tmp)=val;
        tmp++;

        if(tmp>round->end)
                tmp = round->begin;

        if(tmp==round->tail){
                tag=1;
                psudo_head=tmp;
                return(1);
        }
        round->head=tmp;
        return(1);
}

原创粉丝点击