diff options
author | Richard Braun <rbraun@sceen.net> | 2017-07-24 23:30:11 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2017-07-24 23:30:11 +0200 |
commit | f504f743a969a82012a8c60283fe130c1dc5d74f (patch) | |
tree | aa7098e89d9e70ef5c0b3d3915f4525d99333f49 | |
parent | 6e16ff5a6002400489349f55cc7961bccf2fe520 (diff) |
kern/cbuf: update from upstream
-rw-r--r-- | kern/cbuf.c | 48 | ||||
-rw-r--r-- | kern/cbuf.h | 31 | ||||
-rw-r--r-- | kern/console.c | 4 | ||||
-rw-r--r-- | kern/log.c | 2 |
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++; } @@ -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)) { |