打印

一个循环队列的实现(升级版本)

[复制链接]
1204|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
keer_zu|  楼主 | 2022-1-19 14:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


头文件
#ifndef __ROUND_ROBIN__
#define __ROUND_ROBIN__

#define QUE_OK 0
#define QUE_ERR -1

#define QUE_TURN 1
#define QUE_FALSE 0
       

#ifndef NULL
#define NULL ((void *)0)
#endif

typedef struct{
        char *buf;
        unsigned int buf_size;
        int front;
        int rear;
}robin_queue_t;


void queue_init(robin_queue_t *q);
int queue_length(robin_queue_t *q);
int queue_is_full(robin_queue_t *q);
int queue_insert(robin_queue_t *q,char item);
int queue_insert_frame(robin_queue_t *q,char *buff,unsigned int len);
int queue_is_empty(robin_queue_t *q);
char *queue_get_item(robin_queue_t *q);
int queue_del_item(robin_queue_t *q);
int queue_add_index(robin_queue_t *q,unsigned len);
int queue_get_frame(robin_queue_t *q,char *buff);



#endif
  


使用特权

评论回复

相关帖子

沙发
keer_zu|  楼主 | 2022-1-19 14:09 | 只看该作者
实现

/******************************************************************************
                                                                           
File Name:      round_robin_queue.c                                                
Copyright:                                                                             
Version:                                                               
Description:   

Author:                                EMAIL:
Kevin.Zu                          zukeqiang@gmail.com
                                                           
*******************************************************************************
Revision History
-------------------------------------------------------------------------
DATE           NAME                   DESCRIPTION                              
20130515                Kevin.Zu                Create
20131205                Kevin.Zu                Ported to linux
20211213                zukeqiang                ported to tbox

*******************************************************************************/
#include <string.h>
#include <stdio.h>
#include "round_robin_queue.h"
#include "os_depend.h"


#define EC20_RECV_BUF_SIZE 1024

char ec20_recv_buf[EC20_RECV_BUF_SIZE];

robin_queue_t  ec20_recv_queue = {
        .buf = ec20_recv_buf,
        .buf_size = EC20_RECV_BUF_SIZE
};

#define RS485_RECV_BUF_SIZE 1024

char rs485_recv_buf[RS485_RECV_BUF_SIZE];

robin_queue_t  rs485_recv_queue = {
        .buf = rs485_recv_buf,
        .buf_size = RS485_RECV_BUF_SIZE
};



/********************** frame buffer queue ******************************/
void queue_init(robin_queue_t *q)
{
        q->front = 0;
        q->rear = 0;
       
        memset(q->buf,0,q->buf_size);
}

int queue_length(robin_queue_t *q)
{
        if(q == NULL)
                return QUE_ERR;
       
        if(q->rear >= q->front) {
                return q->rear - q->front;
        } else {
                return q->rear + q->buf_size - q->front;
        }
}



int queue_is_full(robin_queue_t *q)
{
        if(q == NULL)
                return QUE_ERR;
       
        if(q->front == (q->rear + 1) % q->buf_size) //
                return QUE_TURN;  
        else  
                return QUE_FALSE;  
}


int queue_insert(robin_queue_t *q,char item)
{
        if(q == NULL)
                return QUE_ERR;  
       
        if(queue_is_full(q))
                return QUE_ERR;  

       
        ENTER_CRITICAL();
        q->buf[q->rear] = item;
        q->rear = (q->rear + 1) % q->buf_size; //
        EXIT_CRITICAL();

       
        return QUE_OK;  

}

int queue_insert_frame(robin_queue_t *q,char *buff,unsigned int len)
{
        int i;
       
        if(q == NULL) {
                return QUE_ERR;  
        }

        if(len > q->buf_size - queue_length(q) -1 ) {
                printf("The data length exceeds the buffer margin!\n");
                return QUE_ERR;
        }

        for(i = 0;i < len;i ++) {
                q->buf[q->rear] = buff[i];
                ENTER_CRITICAL();
                q->rear = (q->rear + 1) % q->buf_size;
                EXIT_CRITICAL();
        }

       
        return QUE_OK;  

}


int queue_is_empty(robin_queue_t *q)
{
        if(q == NULL)
                return QUE_ERR;
       
        if(q->front == q->rear) {
                return QUE_TURN;  
        } else  {
                return QUE_FALSE;  
        }
}

inline char *queue_get_item(robin_queue_t *q)
{
        char *item;
       
        if(!queue_is_empty(q)) {
                item = q->buf + q->front;
               
                ENTER_CRITICAL();
                q->front = (q->front + 1) % q->buf_size;
                EXIT_CRITICAL();
               
                return item;
        } else {
                return NULL;
        }
}

int queue_del_item(robin_queue_t *q)
{  
        if(q == NULL)
                return QUE_ERR;
       
        if(queue_is_empty(q))
                return QUE_ERR;

        ENTER_CRITICAL();
        q->front  = (q->front  + 1) % q->buf_size;  
        EXIT_CRITICAL();

        return QUE_OK;       
}

int queue_add_index(robin_queue_t *q,unsigned len)
{
        if(q == NULL)
                return QUE_ERR;

        ENTER_CRITICAL();
        q->rear = (q->rear + len) % q->buf_size; //
        EXIT_CRITICAL();

        return QUE_OK;
}

int queue_get_frame(robin_queue_t *q,char *buff)
{
        int i = 0;
        if(buff == NULL) {
                return QUE_ERR;
        }
       
        while(!queue_is_empty(q)){
                buff[i] = *(q->buf + q->front);
               
                ENTER_CRITICAL();
                q->front = (q->front + 1) % q->buf_size;
                EXIT_CRITICAL();
                i ++;
        }

        return i;
}


///////////////////////////////////////////// test ////////////////////////////////////

#define TEST_BUF_SIZE 1000
char test_buf[TEST_BUF_SIZE];

robin_queue_t  test_queue = {
        .buf = test_buf,
        .buf_size = TEST_BUF_SIZE
};


void _test_queue(void)
{
        int i;
        char *item = NULL;

        char tbuf[200];
        for(i = 0;i < 200;i ++) {
                tbuf[i] = 100 + i;
        }
       
        queue_init(&test_queue);

        for(i = 1;i < test_queue.buf_size/2;i ++) {
                queue_insert(&test_queue,(char)i);
        }

        printf("====len:%d\n",queue_length(&test_queue));

        while(!queue_is_empty(&test_queue)) {
                item = queue_get_item(&test_queue);
                if(item != NULL) {
                        printf("item:%d  ",*item);
                }
        }

        printf("\n\n");

        int it = test_queue.buf_size/2;

        while(!queue_is_full(&test_queue)) {
                printf("insert:%d  ",it);
                queue_insert(&test_queue,(char)it);
                it ++;
        }

        printf("\n\n");

        printf("====len:%d\n",queue_length(&test_queue));

        queue_insert_frame(&test_queue,tbuf,200);
       
        printf("==++++==len:%d\n",queue_length(&test_queue));

        while(!queue_is_empty(&test_queue)) {
                item = queue_get_item(&test_queue);
                if(item != NULL) {
                        printf("item:%d  ",*item);
                }
        }

        printf("==----==len:%d\n",queue_length(&test_queue));
       
}






使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:qq群:49734243 Email:zukeqiang@gmail.com

1350

主题

12427

帖子

53

粉丝