summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2017-07-24 23:30:11 +0200
committerRichard Braun <rbraun@sceen.net>2017-07-24 23:30:11 +0200
commitf504f743a969a82012a8c60283fe130c1dc5d74f (patch)
treeaa7098e89d9e70ef5c0b3d3915f4525d99333f49
parent6e16ff5a6002400489349f55cc7961bccf2fe520 (diff)
kern/cbuf: update from upstream
-rw-r--r--kern/cbuf.c48
-rw-r--r--kern/cbuf.h31
-rw-r--r--kern/console.c4
-rw-r--r--kern/log.c2
4 files changed, 75 insertions, 10 deletions
diff --git a/kern/cbuf.c b/kern/cbuf.c
index ea848c5..95dd20f 100644
--- a/kern/cbuf.c
+++ b/kern/cbuf.c
@@ -52,16 +52,58 @@ cbuf_update_start(struct cbuf *cbuf)
}
}
-void
-cbuf_push(struct cbuf *cbuf, char byte)
+int
+cbuf_push(struct cbuf *cbuf, const void *buf, size_t size, bool erase)
+{
+ size_t free_size;
+
+ if (!erase) {
+ free_size = cbuf_capacity(cbuf) - cbuf_size(cbuf);
+
+ if (size > free_size) {
+ return ERROR_AGAIN;
+ }
+ }
+
+ return cbuf_write(cbuf, cbuf_end(cbuf), buf, size);
+}
+
+int
+cbuf_pop(struct cbuf *cbuf, void *buf, size_t *sizep)
{
+ int error;
+
+ if (cbuf_size(cbuf) == 0) {
+ return ERROR_AGAIN;
+ }
+
+ error = cbuf_read(cbuf, cbuf_start(cbuf), buf, sizep);
+ assert(!error);
+ cbuf->start += *sizep;
+ return 0;
+}
+
+int
+cbuf_pushb(struct cbuf *cbuf, char byte, bool erase)
+{
+ size_t free_size;
+
+ if (!erase) {
+ free_size = cbuf_capacity(cbuf) - cbuf_size(cbuf);
+
+ if (free_size == 0) {
+ return ERROR_AGAIN;
+ }
+ }
+
cbuf->buf[cbuf_index(cbuf, cbuf->end)] = byte;
cbuf->end++;
cbuf_update_start(cbuf);
+ return 0;
}
int
-cbuf_pop(struct cbuf *cbuf, char *bytep)
+cbuf_popb(struct cbuf *cbuf, char *bytep)
{
if (cbuf_size(cbuf) == 0) {
return ERROR_AGAIN;
diff --git a/kern/cbuf.h b/kern/cbuf.h
index 4d69334..726435d 100644
--- a/kern/cbuf.h
+++ b/kern/cbuf.h
@@ -84,12 +84,35 @@ cbuf_range_valid(const struct cbuf *cbuf, size_t start, size_t end)
void cbuf_init(struct cbuf *cbuf, char *buf, size_t capacity);
/*
+ * Append a buffer to a circular buffer.
+ *
+ * If erasing old data is not allowed, and the circular buffer doesn't have
+ * enough unused bytes for the new data, ERROR_AGAIN is returned. Otherwise,
+ * the end index is increased by the new data size, possibly erasing old
+ * data, in which case, the start index is updated accordingly.
+ */
+int cbuf_push(struct cbuf *cbuf, const void *buf, size_t size, bool erase);
+
+/*
+ * Read bytes from a circular buffer.
+ *
+ * If the buffer is empty, ERROR_AGAIN is returned. Otherwise, the oldest
+ * bytes are stored into the given buffer. On entry, the sizep argument points
+ * to the size of the given buffer. On exit, that value is updated to the
+ * number of bytes actually stored. If successful, the start index is increased
+ * by the amount of bytes read.
+ */
+int cbuf_pop(struct cbuf *cbuf, void *buf, size_t *sizep);
+
+/*
* Append a byte to a circular buffer.
*
- * The end index is incremented. If the buffer is full, the oldest byte
- * is overwritten and the start index is updated accordingly.
+ * If erasing old data is not allowed, and the circular buffer is full,
+ * ERROR_AGAIN is returned. Otherwise, the end index is incremented and, if the
+ * buffer is full, the oldest byte is overwritten and the start index
+ * is updated accordingly.
*/
-void cbuf_push(struct cbuf *cbuf, char byte);
+int cbuf_pushb(struct cbuf *cbuf, char byte, bool erase);
/*
* Read a byte from a circular buffer.
@@ -98,7 +121,7 @@ void cbuf_push(struct cbuf *cbuf, char byte);
* byte is stored at the bytep address, the start index is incremented,
* and 0 is returned.
*/
-int cbuf_pop(struct cbuf *cbuf, char *bytep);
+int cbuf_popb(struct cbuf *cbuf, char *bytep);
/*
* Write into a circular buffer at a specific location.
diff --git a/kern/console.c b/kern/console.c
index 1f9a8a9..ebbdb80 100644
--- a/kern/console.c
+++ b/kern/console.c
@@ -109,7 +109,7 @@ console_getc(struct console *console)
console->waiter = thread_self();
for (;;) {
- error = cbuf_pop(&console->recvbuf, &c);
+ error = cbuf_popb(&console->recvbuf, &c);
if (!error) {
error = console_process_ctrl_char(console, c);
@@ -186,7 +186,7 @@ console_intr(struct console *console, const char *s)
goto out;
}
- cbuf_push(&console->recvbuf, *s);
+ cbuf_pushb(&console->recvbuf, *s, false);
s++;
}
diff --git a/kern/log.c b/kern/log.c
index 3d6ee37..a48afc5 100644
--- a/kern/log.c
+++ b/kern/log.c
@@ -461,7 +461,7 @@ log_write(const void *s, size_t size)
{
int error;
- error = cbuf_write(&log_cbuf, cbuf_end(&log_cbuf), s, size);
+ error = cbuf_push(&log_cbuf, s, size, true);
assert(!error);
if (!cbuf_range_valid(&log_cbuf, log_index, log_index + 1)) {