-
-
Save orazdow/df6a9c6a2cd9170101bc01b2e46b4444 to your computer and use it in GitHub Desktop.
two ring buffers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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"); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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