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);