server: Use ringbuffer for socket backlog
Currently, the socket handler uses a linear buffer for the backlog data;
this means we need to shift up to 128kB of data after each socket
write().
This change introduces a single-producer-multiple-consumer ringbuffer,
to avoid the need for memmove()ing data around; we can simply update
pointers instead of shifting data.
We add this as a new file (ringbuffer.c), to make it a little more
modular. To mitigate the risk of subtle pointer arithmetic issues, we
add a set of tests too.
Change-Id: Ib7c5151d3cf1f588436f5461000b6fed22d0681c
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
diff --git a/console-server.h b/console-server.h
index 2658e89..4d0d5b4 100644
--- a/console-server.h
+++ b/console-server.h
@@ -67,6 +67,33 @@
void console_unregister_poller(struct console *console, struct poller *poller);
+/* ringbuffer API */
+enum ringbuffer_poll_ret {
+ RINGBUFFER_POLL_OK = 0,
+ RINGBUFFER_POLL_REMOVE,
+};
+
+typedef enum ringbuffer_poll_ret (*ringbuffer_poll_fn_t)(void *data,
+ size_t force_len);
+
+struct ringbuffer;
+struct ringbuffer_consumer;
+
+struct ringbuffer *ringbuffer_init(size_t size);
+void ringbuffer_fini(struct ringbuffer *rb);
+
+struct ringbuffer_consumer *ringbuffer_consumer_register(struct ringbuffer *rb,
+ ringbuffer_poll_fn_t poll_fn, void *data);
+
+void ringbuffer_consumer_unregister(struct ringbuffer_consumer *rbc);
+
+int ringbuffer_queue(struct ringbuffer *rb, uint8_t *data, size_t len);
+
+size_t ringbuffer_dequeue_peek(struct ringbuffer_consumer *rbc, size_t offset,
+ uint8_t **data);
+
+int ringbuffer_dequeue_commit(struct ringbuffer_consumer *rbc, size_t len);
+
/* config API */
struct config;
const char *config_get_value(struct config *config, const char *name);