C; ring buffer; is this "doable" approach?
Posted: Mon Jan 23, 2023 10:07 am
I needed to create ring buffer for my keyboard driver. While I need only to buffer bytes(chars) I was wondering if I can implement more versatile approach if I need it for something else. I did create this but I'm not sure if I'm not pushing it too much.
Here's the implementation:
With test program:
Is this acceptable form of such definition ? I never used macros like these. I mean, it does compile, it doesn't complain. But I'm just not sure if that's a good idea.
Here's the implementation:
Code: Select all
#ifndef HAVE_TYPES_H
#define HAVE_TYPES_H
#include <stdint.h>
#define RINGBUF32_SIZE 32
#define DEFINE_RING32(name, type) \
struct rbuf32 { \
uint8_t ri:5; \
uint8_t ci:5; \
type buf[RINGBUF32_SIZE];\
} rbuf32_t; \
typedef struct rbuf32 name;
#define STORE_RING32(rb, item) do { \
(rb)->buf[(rb)->ci++] = (item); \
} while(0)
#define FETCH_RING32(rb) (rb)->buf[(rb)->ri++]
#endif /* ifndef HAVE_TYPES_H */
Code: Select all
#include <stdio.h>
#include <string.h>
#include "types.h"
#define SANITY_CHECK 2048
DEFINE_RING32(dbuf32, int)
void dumpbuf(void* b);
int main() {
dbuf32 buf;
dbuf32* pbuf = &buf; // XXX: due to way macros are defined
int d,i;
memset(&buf, 0, sizeof(buf));
i =0;
while(1) {
scanf("%d", &d);
printf("storing: %d\n", d);
STORE_RING32(pbuf, d);
if (i++ > SANITY_CHECK || d == 42) {
break;
}
}
dumpbuf(pbuf);
for (i=0; i < 6; i++) {
printf("fetch: %d\n", FETCH_RING32(pbuf));
}
dumpbuf(pbuf);
return 0;
}
void dumpbuf(void* b) {
dbuf32* buf = (dbuf32*)b;
printf("ri: %d, ci: %d\n", buf->ri, buf->ci);
for(int i =0; i < 32; i++) {
printf("%d ", buf->buf[i]);
}
printf("\n");
}