Skip to content

Instantly share code, notes, and snippets.

@orazdow
Last active May 7, 2018 03:05
Show Gist options
  • Save orazdow/df6a9c6a2cd9170101bc01b2e46b4444 to your computer and use it in GitHub Desktop.
Save orazdow/df6a9c6a2cd9170101bc01b2e46b4444 to your computer and use it in GitHub Desktop.
two ring buffers
#include "ringbuffer.h"
#include "stdlib.h"
size_t rb_push(RingBuffer* r, short* data, size_t num){
size_t written = 0;
while((r->head+1) % r->size != r->tail && written != num){
r->buffer[r->head] = *data++;
r->head = (r->head+1) % r->size;
written++;
}
return written;
}
size_t rb_pop(RingBuffer* r, short* data, size_t num){
size_t written = 0;
while(r->tail != r->head && written != num){
*data++ = r->buffer[r->tail];
r->tail = (r->tail+1) % r->size;
written++;
}
return written;
}
size_t rb_pushAvail(RingBuffer* r){
if(r->head > r->tail){
return (r->size - r->head) + r->tail;
}else if(r->head < r->tail){
return r->tail - r->head;
}else{
return r->size;
}
}
size_t rb_popAvail(RingBuffer* r){
if(r->head > r->tail){
return r->head - r->tail;
}else if(r->head < r->tail){
return r->head + (r->size - r->tail);
}else{
return 0;
}
}
int rb_init(RingBuffer* r, short* buff, size_t size){
r->size = size;
if(buff == NULL){
r->buffer = (short*)malloc(size*sizeof(short));
}else{
r->buffer = (short*)buff;
}
r->head = 0;
r->tail = 0;
if(r->buffer == NULL)
return -1;
return 0;
}
void rb_destroy(RingBuffer* r){
free(r->buffer);
}
#include "ringbuffer.h"
#include "stdlib.h"
#include "string.h"
int rb_init(RingBuffer* r, void* buff, size_t size, size_t elementSize){
r->size = size;
r->elsize = elementSize;
if(buff == NULL){
r->buffer = (char*)malloc(size*elementSize);
}else{
r->buffer = (char*)buff;
}
r->head = 0;
r->tail = 0;
if(r->buffer == NULL)
return -1;
return 0;
}
void rb_destroy(RingBuffer* r){
free(r->buffer);
}
size_t rb_push(RingBuffer* r, void* data, size_t num){
size_t written = 0;
if(r->head >= r->tail){
size_t bregion = r->size - r->head;
if(num <= bregion){
memcpy(r->buffer + r->head*r->elsize, data, num*r->elsize);
r->head = r->head + num;
written = num;
}else{
memcpy(r->buffer + r->head*r->elsize, data, bregion*r->elsize);
r->head = r->size-1;
written = bregion;
// data = ((char *)data) + bregion*r->elsize;
if(r->tail > 0){
size_t remaining = (num-written < r->tail-1) ? num-written : r->tail-1;
r->head = 0;
memcpy(r->buffer + r->head*r->elsize, (char*)data+(bregion*r->elsize), remaining*r->elsize);
r->head = remaining;
written = written + r->head;
}
}
}else{
size_t bregion = r->tail - (r->head+1);
if(num <= bregion){
memcpy(r->buffer + r->head*r->elsize, data, num*r->elsize);
r->head = r->head + num;
written = num;
}else{
memcpy(r->buffer + r->head*r->elsize, data, bregion*r->elsize);
r->head = r->head + bregion;
written = bregion;
}
}
return written;
}
size_t rb_pop(RingBuffer* r, void* data, size_t num){
size_t written = 0;
if(r->head >= r->tail){
size_t available = (r->head - r->tail);
if(available == 0){ return 0; }
if(num <= available){
memcpy(data, &r->buffer[r->tail*r->elsize], num*r->elsize);
r->tail = r->tail + num;
written = num;
}else{
memcpy(data, &r->buffer[r->tail*r->elsize], available*r->elsize);
r->tail = r->tail + available;
written = available;
}
}else{
if(num <= (r->size - r->tail)){
memcpy(data, &r->buffer[r->tail*r->elsize], num*r->elsize);
r->tail = r->tail + num;
written = num;
}else{
memcpy(data, &r->buffer[r->tail*r->elsize], (r->size - r->tail)*r->elsize);
written = (r->size - r->tail);
r->tail = 0;
if(r->head > 0 && written < num){
size_t remaining = num < r->head ? num : r->head;
memcpy((char*)data+written*r->elsize, &r->buffer[r->tail*r->elsize], remaining*r->elsize);
r->tail = r->tail + remaining;
written = written + remaining;
}
}
}
return written;
}
size_t rb_pushAvail(RingBuffer* r){
if(r->head > r->tail){
return r->head = r->tail;
}else if(r->head < r->tail){
return r->head + (r->size - r->tail);
}else{
return 0;
}
}
size_t rb_popAvail(RingBuffer* r){
if(r->head > r->tail){
return (r->size - r->head) + r->tail;
}else if(r->head < r->tail){
return r->tail - r->head;
}else{
return r->size;
}
}
#ifndef RINGBUFF_H
#define RINGBUFF_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stddef.h"
typedef struct{
short* buffer;
size_t head;
size_t tail;
size_t size;
size_t elsize;
}RingBuffer;
int rb_init(RingBuffer* r, short* buff, size_t size);
void rb_destroy(RingBuffer* r);
size_t rb_push(RingBuffer* r, short* data_in, size_t num);
size_t rb_pop(RingBuffer* r, short* data_out, size_t num);
size_t rb_pushAvail(RingBuffer* r);
size_t rb_popAvail(RingBuffer* r);
#ifdef __cplusplus
}
#endif
#endif /* RINGBUFF_H */
#include "ringbuffer.h"
#include "stdlib.h"
#include "stdio.h"
#include "assert.h"
//short* data = (short*)malloc(32768*sizeof(short));
RingBuffer rb;
//size_t written = 0;
// char data[12];
char id[1200];
char* indata = &id[0];
//or char* indata = (char*)a;
char od[120];
char* outdata = &od[0];
int main(){
srand(99);
for(int i = 0; i < 1200; i++){
indata[i] = rand();
if(i < 12)
printf("%u, ", indata[i]);
}
printf("\n");
rb_init(&rb, NULL, 12, 1);
printf("h: %u t: %u\n", rb.head, rb.tail);
rb_push(&rb, indata, 10);
indata+= 10;
printf("h: %u t: %u\n", rb.head, rb.tail);
int rcv = rb_pop(&rb, outdata, 100);
printf("received: %u\n", rcv);
printf("h: %u t: %u\n", rb.head, rb.tail);
for(int i = 0; i < rcv; i++){
printf("%u ", outdata[i]);
}printf("\n");
int w = rb_push(&rb, indata, 6);
printf("wrote: %u\n", w);
printf("h: %u t: %u\n", rb.head, rb.tail);
printf("hi\n");
int r = rb_pop(&rb, outdata+rcv, 10);
printf("received: %u\n", r);
printf("h: %u t: %u\n", rb.head, rb.tail);
for(int i = 0; i < rcv+r; i++){
printf("%u ", outdata[i]);
}printf("\n");
rb_destroy(&rb);
printf("bye\n");
}
/* Public domain. */
/* gcc memcpy */
#include <stddef.h>
void *
memcpy (void *dest, const void *src, size_t len)
{
char *d = dest;
const char *s = src;
while (len--)
*d++ = *s++;
return dest;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment