prosperon/source/engine/cbuf.h
2023-11-27 20:29:55 +00:00

53 lines
1.2 KiB
C

#ifndef CIRCBUF_H
#define CIRCBUF_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
static inline unsigned int powof2(unsigned int x)
{
x = x-1;
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return x+1;
}
struct rheader
{
unsigned int read;
unsigned int write;
int len;
};
#define ringheader(r) ((struct rheader *)r-1)
static inline void *ringmake(void *ring, size_t elemsize, unsigned int n)
{
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)
#endif