summaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authorAllan Stephens <allan.stephens@windriver.com>2016-10-18 16:02:43 -0500
committerBenjamin Walsh <benjamin.walsh@windriver.com>2016-10-21 15:33:31 +0000
commitb9a4bd906c8b4d6edbc8cbd94668bde7fdcb71ca (patch)
treebf8cab2ebe0a0f33b42eb8c82224e4f5a0a34cc8 /misc
parent729fdf8ec8a607b35cda932dccd36b7b03892424 (diff)
kernel: Relocate ring buffer suppport to 'misc' directory
Moves the source code for ring buffers to the 'misc' area, since it isn't really a central component of the kernel. (This also aligns the ring buffer source code with its include file, which is already under 'include/misc'.) Change-Id: I765a383a05f51fa67d154446f412496e689f9702 Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
Diffstat (limited to 'misc')
-rw-r--r--misc/Makefile1
-rw-r--r--misc/ring_buffer.c104
2 files changed, 105 insertions, 0 deletions
diff --git a/misc/Makefile b/misc/Makefile
index cb9a718d9..0072021de 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -3,5 +3,6 @@ obj-$(CONFIG_CPLUSPLUS) += cpp_virtual.o cpp_vtable.o \
cpp_init_array.o cpp_ctors.o cpp_dtors.o
obj-$(CONFIG_PRINTK) += printk.o
obj-$(CONFIG_REBOOT) += reboot.o
+obj-$(CONFIG_RING_BUFFER) += ring_buffer.o
obj-y += generated/
obj-y += debug/
diff --git a/misc/ring_buffer.c b/misc/ring_buffer.c
new file mode 100644
index 000000000..21cdab63a
--- /dev/null
+++ b/misc/ring_buffer.c
@@ -0,0 +1,104 @@
+/* ring_buffer.c: Simple ring buffer API */
+
+/*
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <misc/ring_buffer.h>
+
+/**
+ * Internal data structure for a buffer header.
+ *
+ * We want all of this to fit in a single uint32_t. Every item stored in the
+ * ring buffer will be one of these headers plus any extra data supplied
+ */
+struct ring_element {
+ uint32_t type :16; /**< Application-specific */
+ uint32_t length :8; /**< length in 32-bit chunks */
+ uint32_t value :8; /**< Room for small integral values */
+};
+
+int sys_ring_buf_put(struct ring_buf *buf, uint16_t type, uint8_t value,
+ uint32_t *data, uint8_t size32)
+{
+ uint32_t i, space, index, rc;
+
+ space = sys_ring_buf_space_get(buf);
+ if (space >= (size32 + 1)) {
+ struct ring_element *header =
+ (struct ring_element *)&buf->buf[buf->tail];
+ header->type = type;
+ header->length = size32;
+ header->value = value;
+
+ if (likely(buf->mask)) {
+ for (i = 0; i < size32; ++i) {
+ index = (i + buf->tail + 1) & buf->mask;
+ buf->buf[index] = data[i];
+ }
+ buf->tail = (buf->tail + size32 + 1) & buf->mask;
+ } else {
+ for (i = 0; i < size32; ++i) {
+ index = (i + buf->tail + 1) % buf->size;
+ buf->buf[index] = data[i];
+ }
+ buf->tail = (buf->tail + size32 + 1) % buf->size;
+ }
+ rc = 0;
+ } else {
+ buf->dropped_put_count++;
+ rc = -EMSGSIZE;
+ }
+
+ return rc;
+}
+
+int sys_ring_buf_get(struct ring_buf *buf, uint16_t *type, uint8_t *value,
+ uint32_t *data, uint8_t *size32)
+{
+ struct ring_element *header;
+ uint32_t i, index;
+
+ if (sys_ring_buf_is_empty(buf)) {
+ return -EAGAIN;
+ }
+
+ header = (struct ring_element *) &buf->buf[buf->head];
+
+ if (header->length > *size32) {
+ *size32 = header->length;
+ return -EMSGSIZE;
+ }
+
+ *size32 = header->length;
+ *type = header->type;
+ *value = header->value;
+
+ if (likely(buf->mask)) {
+ for (i = 0; i < header->length; ++i) {
+ index = (i + buf->head + 1) & buf->mask;
+ data[i] = buf->buf[index];
+ }
+ buf->head = (buf->head + header->length + 1) & buf->mask;
+ } else {
+ for (i = 0; i < header->length; ++i) {
+ index = (i + buf->head + 1) % buf->size;
+ data[i] = buf->buf[index];
+ }
+ buf->head = (buf->head + header->length + 1) % buf->size;
+ }
+
+ return 0;
+}