diff options
author | June McEnroe <june@causal.agency> | 2019-10-29 23:04:58 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2019-10-29 23:04:58 -0400 |
commit | eeac134e697f77d85ecbb8d6bd572a4b592433aa (patch) | |
tree | 611c18cdc27f146aa96ec3f5c652dd4fc0466ea2 | |
parent | Do not duplicate origin on nick change (diff) | |
download | pounce-eeac134e697f77d85ecbb8d6bd572a4b592433aa.tar.gz pounce-eeac134e697f77d85ecbb8d6bd572a4b592433aa.zip |
Allocate ring buffer at runtime
-rw-r--r-- | bounce.c | 4 | ||||
-rw-r--r-- | bounce.h | 1 | ||||
-rw-r--r-- | ring.c | 36 |
3 files changed, 25 insertions, 16 deletions
diff --git a/bounce.c b/bounce.c index 79a75f2..2a7acd4 100644 --- a/bounce.c +++ b/bounce.c @@ -180,11 +180,11 @@ int main(int argc, char *argv[]) { if (!user) user = nick; if (!real) real = nick; + ringAlloc(4096); if (save) saveLoad(save); - listenConfig(certPath, privPath); - int bind[8]; + listenConfig(certPath, privPath); size_t binds = listenBind(bind, 8, bindHost, bindPort); int server = serverConnect(insecure, host, port); diff --git a/bounce.h b/bounce.h index c37ff61..5e6313b 100644 --- a/bounce.h +++ b/bounce.h @@ -59,6 +59,7 @@ static inline struct Message parse(char *line) { return msg; } +void ringAlloc(size_t len); void ringProduce(const char *line); size_t ringConsumer(const char *name); size_t ringDiff(size_t consumer); diff --git a/ring.c b/ring.c index 474a6e4..0fec6d0 100644 --- a/ring.c +++ b/ring.c @@ -23,18 +23,25 @@ #include "bounce.h" -enum { RingLen = 4096 }; -static_assert(!(RingLen & (RingLen - 1)), "power of two RingLen"); - static struct { - char *lines[RingLen]; - time_t times[RingLen]; + size_t len; + char **lines; + time_t *times; } ring; +void ringAlloc(size_t len) { + if (len & (len - 1)) errx(EX_CONFIG, "ring length must be power of two"); + ring.lines = calloc(len, sizeof(*ring.lines)); + if (!ring.lines) err(EX_OSERR, "calloc"); + ring.times = calloc(len, sizeof(*ring.times)); + if (!ring.times) err(EX_OSERR, "calloc"); + ring.len = len; +} + size_t producer; void ringProduce(const char *line) { - size_t i = producer++ % RingLen; + size_t i = producer++ & (ring.len - 1); if (ring.lines[i]) free(ring.lines[i]); ring.times[i] = time(NULL); ring.lines[i] = strdup(line); @@ -79,17 +86,18 @@ size_t ringDiff(size_t consumer) { const char *ringPeek(time_t *time, size_t consumer) { if (!ringDiff(consumer)) return NULL; - if (ringDiff(consumer) > RingLen) { - consumers.ptr[consumer].pos = producer - RingLen; + if (ringDiff(consumer) > ring.len) { + consumers.ptr[consumer].pos = producer - ring.len; } - size_t i = consumers.ptr[consumer].pos % RingLen; + size_t i = consumers.ptr[consumer].pos & (ring.len - 1); if (time) *time = ring.times[i]; + assert(ring.lines[i]); return ring.lines[i]; } const char *ringConsume(time_t *time, size_t consumer) { const char *line = ringPeek(time, consumer); - consumers.ptr[consumer].pos++; + if (line) consumers.ptr[consumer].pos++; return line; } @@ -124,10 +132,10 @@ int ringSave(FILE *file) { if (writeString(file, consumers.ptr[i].name)) return -1; if (writeSize(file, consumers.ptr[i].pos)) return -1; } - for (size_t i = 0; i < RingLen; ++i) { + for (size_t i = 0; i < ring.len; ++i) { if (writeTime(file, ring.times[i])) return -1; } - for (size_t i = 0; i < RingLen; ++i) { + for (size_t i = 0; i < ring.len; ++i) { if (!ring.lines[i]) break; if (writeString(file, ring.lines[i])) return -1; } @@ -169,10 +177,10 @@ void ringLoad(FILE *file) { readSize(file, &consumers.ptr[consumer].pos); } - for (size_t i = 0; i < RingLen; ++i) { + for (size_t i = 0; i < ring.len; ++i) { readTime(file, &ring.times[i]); } - for (size_t i = 0; i < RingLen; ++i) { + for (size_t i = 0; i < ring.len; ++i) { readString(file, &buf, &cap); if (feof(file)) break; ring.lines[i] = strdup(buf); |