使用C实现了一个循环队列

以下链接为C的循环队列实现,

如有需要,有兴趣,请自由的克隆,更改,

如果此代码对你有所帮助将使我非常高兴,如果有任何bug,请自行更改,并可提交给我,我将merge到主分支。

源码:

https://github.com/youchongping/ring

若不慎给了个star,fork我将会快乐到飞起!

上诉代码没有OS互斥,若用于OS需保证只能一个地方写,一个地方读,不能多处读写。

字符串型队列实现,可入列任意结构体or固定长度数组,当然也可以单个字符(效果就和上述字符型队列一样了),可用于OS,互斥函数需自行适配不同OS:

 

#include "ring.h"

int ring_create(RB* r, unsigned char* buf, int size)
{
    if(buf == NULL)return RING_CREATE_FAILED;
    r->ptr_o = buf;
    r->ptr_w = 0;
    r->ptr_r = 0;
    r->size  = size;
    return RING_SCUCESS;
}

int ring_putchar(RB* r, unsigned char c)
{
    if(ring_is_full(r)) return RING_PUT_FAILED;

    *(r->ptr_o + r->ptr_w) = c;
    r->ptr_w = (r->ptr_w + 1) % (r->size);

    return RING_SCUCESS;
}

int ring_getchar(RB* r, unsigned char* c)
{
    if(ring_is_empty(r))return RING_GET_FAILED;

    *c = *(r->ptr_o + r->ptr_r);
    r->ptr_r = (r->ptr_r + 1) % (r->size);
    return RING_SCUCESS;
}

int ring_puts(RB* r, unsigned char*buf, int buf_len)
{
    while(buf_len)
    {
        if(ring_putchar(r, *buf) < 0)
        {
            return RING_PUTS_FAILED;
        }
        buf++;
        buf_len--;

    }
    return RING_SCUCESS;
}

int ring_gets(RB* r, unsigned char* buf, int len_tryto_read, int* len_actual_read)
{
    *len_actual_read = 0;
    while(*len_actual_read < len_tryto_read)
    {
        if(ring_getchar(r, buf) < 0)
        {
            return RING_GETS_FAILED;
        }
        (*len_actual_read)++;
        buf++;
    }

    return RING_SCUCESS;
}
/**********other functions may need**************/
int ring_reset(RB*r)
{
    if(r->ptr_o == NULL)
    {
        return RING_RESET_FAILED;
    }

    r->ptr_w = 0;
    r->ptr_r = 0;
    return RING_SCUCESS;
}
int ring_get_count(RB*r)
{
    return (r->ptr_w + r->size - r->size) % (r->size);
}

int ring_get_remain(RB* r)
{
    return (r->ptr_r - r->ptr_w - 1 + r->size) % (r->size);
}
int ring_is_empty(RB* r)
{
    return  (r->ptr_r == r->ptr_w);
}

int ring_is_full(RB* r)
{
    return (((r->ptr_w + 1) % (r->size)) == r->ptr_r);
}

int ring_perror(char* fmt, int error)
{
    return 0;
}
#ifndef __RING_H_
#define __RING_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum
{
    RING_GETS_FAILED = -6,
    RING_PUTS_FAILED = -5,
    RING_GET_FAILED = -4,
    RING_PUT_FAILED = -3,
    RING_RESET_FAILED = -2,
    RING_CREATE_FAILED = -1,
    RING_SCUCESS = 0,
};
//ring  structure
typedef struct
{
    int size;//the size of ring's effective capacity
    unsigned char* ptr_o;//origin address
    unsigned int ptr_r;//next read address
    unsigned int ptr_w;//next write address
} RB;
/**********funtions always use*************/
int ring_create(RB* r, unsigned char* buf, int size);
int ring_putchar(RB* r, unsigned char c);
int ring_getchar(RB* r, unsigned char* c);
int ring_puts(RB* r, unsigned char*buf, int buf_len);
int ring_gets(RB* r, unsigned char* buf, int len_tryto_read, int* len_actual_read);
/**********funtions may need*************/
int ring_reset(RB*r);
int ring_get_count(RB*r);
int ring_get_remain(RB* r);
int ring_is_empty(RB* r);
int ring_is_full(RB* r);
int ring_perror(char* fmt, int error);
#endif
#include "rings.h"
#include "malloc.h"
#include "os.h"
static unsigned char mutex_index = 0;
/*need user realize,or use malloc*/
void* rings_malloc(unsigned int size)
{
    //return malloc(size);
    return mymalloc(FS_USE, size);
}
void rings_free(void *ptr)
{
    //free(size);
    myfree(FS_USE, ptr);
}

/*OS needs*/


void rings_MutexInit(RBS* r)
{
    #if RINGS_OS_EN
    OS_ERR err;
    char name[10];
    snprintf(name, sizeof(name), "mutex_%02X", mutex_index);
    mutex_index++;
    OSMutexCreate(&(r->rings_mutex), name, &err);
    #else
    #endif
    return;
}

OS_ERR rings_MutexTake(RBS* r)
{
    #if RINGS_OS_EN
    OS_ERR err;

    OSMutexPend(&(r->rings_mutex), 0, OS_OPT_PEND_BLOCKING, 0, &err);
    return err;
    #else
    return 0;
    #endif
}
OS_ERR rings_MutexRelease(RBS* r)
{
    #if RINGS_OS_EN
    OS_ERR err;
    OSMutexPost(&(r->rings_mutex), OS_OPT_POST_NONE,  &err);
    return err;
    #else
    return 0;
    #endif
}

int rings_create(RBS* r, unsigned int qty, unsigned int element_size)
{
    if((qty == 0) || (element_size == 0) || (r == NULL))return RINGS_CREATE_FAILED;
    r->ptr_o = (unsigned char*)rings_malloc(qty * element_size);
    if(r->ptr_o == NULL)return RINGS_CREATE_FAILED;
    rings_MutexInit(r);
    r->ptr_w = 0;
    r->ptr_r = 0;
    r->size = qty * element_size;
    r->element_size = element_size;
    r->qty = qty;
    return RINGS_SCUCESS;
}
int rings_destroy(RBS* r)
{
    rings_free(r->ptr_o);
    r->ptr_o = NULL;
    r->ptr_w = 0;
    r->ptr_r = 0;
    return RINGS_SCUCESS;
}
static int rings_putchar(RBS* r, unsigned char c)
{
    if(rings_is_full(r) || (r->ptr_o == NULL) || (r == NULL)) return RINGS_PUT_FAILED;


    *(r->ptr_o + r->ptr_w) = c;
    r->ptr_w = (r->ptr_w + 1) % (r->size);

    return RINGS_SCUCESS;
}

static int rings_getchar(RBS* r, unsigned char* c)
{
    if(rings_is_empty(r) || (r->ptr_o == NULL) || (r == NULL))return RINGS_GET_FAILED;


    *c = *(r->ptr_o + r->ptr_r);
    r->ptr_r = (r->ptr_r + 1) % (r->size);

    return RINGS_SCUCESS;
}

int rings_puts(RBS* r, unsigned char* buf, unsigned int buf_len)
{
    rings_MutexTake(r);

    if((r->ptr_o == NULL) || (r->element_size != buf_len) || (r == NULL))
    {
        rings_MutexRelease(r);
        return RINGS_PUTS_FAILED;
    }
    while(buf_len)
    {
        if(rings_putchar(r, *buf) < 0)
        {
            rings_perror("rings_putchar() ", RINGS_PUT_FAILED);
            rings_MutexRelease(r);
            return RINGS_PUTS_FAILED;
        }
        buf++;
        buf_len--;

    }
    r->count_s++;
    rings_MutexRelease(r);
    return RINGS_SCUCESS;
}

int rings_gets(RBS* r, unsigned char* buf, unsigned int len_to_read)
{
    rings_MutexTake(r);
    int len_actual_read = 0;
    if((r->element_size != len_to_read) || (r == NULL))
    {
        rings_MutexRelease(r);
        return RINGS_GETS_FAILED;

    }
    while(len_actual_read < len_to_read)
    {
        if(rings_getchar(r, buf) < 0)
        {
            rings_MutexRelease(r);
            return RINGS_GETS_FAILED;
        }
        (len_actual_read)++;
        buf++;
    }
    r->count_s--;
    rings_MutexRelease(r);
    return RINGS_SCUCESS;
}
/**********other functions may need**************/
int rings_reset(RBS * r)
{
    if(r->ptr_o == NULL)
    {
        return RINGS_RESET_FAILED;
    }

    r->ptr_w = 0;
    r->ptr_r = 0;
    return RINGS_SCUCESS;
}
int rings_get_count(RBS*r)
{
    return (r->ptr_w + r->size - r->size) % (r->size);
}

int rings_get_remain(RBS* r)
{
    return (r->ptr_r - r->ptr_w - 1 + r->size) % (r->size);
}
int rings_is_empty(RBS* r)
{
    return  (r->ptr_r == r->ptr_w);
}

int rings_is_full(RBS* r)
{
    return (((r->ptr_w + 1) % (r->size)) == r->ptr_r);
}

int rings_perror(char* fmt, int error)
{
    return 0;
}
#ifndef __RINGS_H_
#define __RINGS_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "os.h"

#define RINGS_OS_EN (0) // is os exsit?
enum
{
    RINGS_GETS_FAILED = -6,
    RINGS_PUTS_FAILED = -5,
    RINGS_GET_FAILED = -4,
    RINGS_PUT_FAILED = -3,
    RINGS_RESET_FAILED = -2,
    RINGS_CREATE_FAILED = -1,
    RINGS_SCUCESS = 0,
};
//ring  structure
typedef struct
{
    unsigned int qty;
    unsigned int element_size;
    unsigned int size;//the size of ring's effective capacity
    unsigned char* ptr_o;//origin address
    unsigned int ptr_r;//next read address
    unsigned int ptr_w;//next write address
    unsigned int count_s;// struct count
    #if RINGS_OS_EN
    OS_MUTEX rings_mutex;
    #endif
} RBS;
/**********funtions always use*************/
int rings_create(RBS* r, unsigned int qty, unsigned int element_size);
int rings_puts(RBS* r, unsigned char* buf, unsigned int buf_len);
int rings_gets(RBS* r, unsigned char* buf, unsigned int len_to_read);

/**********funtions may need*************/
int rings_reset(RBS*r);
int rings_get_count(RBS*r);
int rings_get_remain(RBS* r);
int rings_is_empty(RBS* r);
int rings_is_full(RBS* r);
int rings_perror(char* fmt, int error);
#endif

 

posted @ 2019-07-24 00:23  =没有编程天赋=  阅读(391)  评论(1)    收藏  举报