prosperon/source/engine/cbuf.h

52 lines
1.2 KiB
C
Raw Normal View History

2023-08-30 18:22:32 -05:00
#ifndef CIRCBUF_H
#define CIRCBUF_H
2024-02-23 16:05:30 -06:00
#include <stdlib.h>
2023-08-30 18:22:32 -05:00
#include <stdint.h>
2023-11-27 14:29:55 -06:00
static inline unsigned int powof2(unsigned int x)
2023-08-30 18:22:32 -05:00
{
2023-11-27 14:29:55 -06:00
x = x-1;
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return x+1;
2023-08-30 18:22:32 -05:00
}
2023-11-27 14:29:55 -06:00
struct rheader
2023-08-30 18:22:32 -05:00
{
2023-11-27 14:29:55 -06:00
unsigned int read;
unsigned int write;
int len;
};
2023-08-30 18:22:32 -05:00
2023-11-27 14:29:55 -06:00
#define ringheader(r) ((struct rheader *)r-1)
2023-08-30 18:22:32 -05:00
2023-11-27 14:29:55 -06:00
static inline void *ringmake(void *ring, size_t elemsize, unsigned int n)
2023-08-30 18:22:32 -05:00
{
2023-11-27 14:29:55 -06:00
n = powof2(n);
if (ring) {
struct rheader *h = ringheader(ring);
if (n <= h->len) return h+1;
h = realloc(h, elemsize*n+sizeof(struct rheader));
return h+1;
}
struct rheader *h = malloc(elemsize*n+sizeof(struct rheader));
h->len = n; h->read = 0; h->write = 0;
return h+1;
}
#define ringnew(r,n) (r = ringmake(r, sizeof(*r),n))
#define ringfree(r) ((r) ? free(ringheader(r)) : 0)
#define ringmask(r,v) (v & (ringheader(r)->len-1))
#define ringpush(r,v) (r[ringmask(r,ringheader(r)->write++)] = v)
#define ringshift(r) (r[ringmask(r,ringheader(r)->read++)])
#define ringsize(r) ((r) ? ringheader(r)->write - ringheader(r)->read : 0)
#define ringfull(r) ((r) ? ringsize(r) == ringheader(r)->len : 0)
#define ringempty(r) ((r) ? ringheader(r)->read == ringheader(r)->write : 0)
2023-08-30 18:22:32 -05:00
#endif