summaryrefslogtreecommitdiff
path: root/kern/mbuf.h
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2019-01-07 23:00:40 +0100
committerRichard Braun <rbraun@sceen.net>2019-04-24 01:09:03 +0200
commitb99a7a8477947305489d3fbc8db57e7e1511272e (patch)
tree088e34b97314b4d3b98cffeca7c7163b8eb77f22 /kern/mbuf.h
parent558e96c137bdd7cf7b8f2fac0cadddeb32c830bc (diff)
kern/mbuf: new module
Diffstat (limited to 'kern/mbuf.h')
-rw-r--r--kern/mbuf.h125
1 files changed, 125 insertions, 0 deletions
diff --git a/kern/mbuf.h b/kern/mbuf.h
new file mode 100644
index 00000000..1c36afb5
--- /dev/null
+++ b/kern/mbuf.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2018-2019 Richard Braun.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Upstream site with license notes :
+ * http://git.sceen.net/rbraun/librbraun.git/
+ *
+ *
+ * FIFO message buffer.
+ */
+
+#ifndef KERN_MBUF_H
+#define KERN_MBUF_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#include <kern/cbuf.h>
+
+/*
+ * Message buffer.
+ *
+ * Message buffers are built on top of circular byte buffers. They provide
+ * discrete message transfer from a producer to a consumer.
+ *
+ * The order is computed from the maximum message size, and is used to
+ * determine a header size that can represent up to 2^order - 1 bytes.
+ */
+struct mbuf {
+ struct cbuf cbuf;
+ size_t max_msg_size;
+ unsigned int order;
+};
+
+static inline size_t
+mbuf_start(const struct mbuf *mbuf)
+{
+ return cbuf_start(&mbuf->cbuf);
+}
+
+static inline size_t
+mbuf_end(const struct mbuf *mbuf)
+{
+ return cbuf_end(&mbuf->cbuf);
+}
+
+/*
+ * Initialize a message buffer.
+ *
+ * The descriptor is set to use the given buffer for storage. Capacity
+ * must be a power-of-two.
+ */
+void mbuf_init(struct mbuf *mbuf, void *buf, size_t capacity,
+ size_t max_msg_size);
+
+/*
+ * Clear a message buffer.
+ */
+void mbuf_clear(struct mbuf *mbuf);
+
+/*
+ * Push a message to a message buffer.
+ *
+ * If the message doesn't fit in the message buffer, either because it is
+ * larger than the capacity, or because the function isn't allowed to erase
+ * old messages and the message buffer doesn't have enough available memory
+ * for the new message, EMSGSIZE is returned. If the message is larger than
+ * the maximum message size, EINVAL is returned.
+ */
+int mbuf_push(struct mbuf *mbuf, const void *buf, size_t size, bool erase);
+
+/*
+ * Pop a message from a message buffer.
+ *
+ * On entry, the sizep argument points to the size of the output buffer.
+ * On return, it is updated to the size of the message. If the message
+ * doesn't fit in the output buffer, it is not popped, EMSGSIZE is
+ * returned, but the sizep argument is updated nonetheless to let the
+ * user know the message size, to potentially retry with a larger buffer.
+ *
+ * If the buffer is empty, EAGAIN is returned, and the size of the output
+ * buffer is unmodified.
+ *
+ * The output buffer may be NULL, in which case this function acts as if
+ * it wasn't, but without writing output data.
+ */
+int mbuf_pop(struct mbuf *mbuf, void *buf, size_t *sizep);
+
+/*
+ * Read a message from a message buffer.
+ *
+ * On entry, the indexp argument points to the index of the message to
+ * read in the message buffer, and the sizep argument points to the size
+ * of the output buffer. On return, if successful, indexp is updated
+ * to the index of the next message, and sizep to the size of the
+ * message read.
+ *
+ * If the message doesn't fit in the output buffer, it is not read,
+ * EMSGSIZE is returned, and the sizep argument is updated nonetheless
+ * to let the user know the message size, to potentially retry with a
+ * larger buffer.
+ *
+ * If the given index refers to the end of the buffer, then EAGAIN is
+ * returned. If it's outside buffer boundaries, EINVAL is returned.
+ * Otherwise, if it doesn't point to the beginning of a message, the
+ * behavior is undefined.
+ *
+ * The message buffer isn't changed by this operation.
+ */
+int mbuf_read(const struct mbuf *mbuf, size_t *indexp,
+ void *buf, size_t *sizep);
+
+#endif /* KERN_MBUF_H */