Skip to content

Commit

Permalink
ring_buf: refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
mosmeh committed Jul 5, 2024
1 parent 61b5bd4 commit b50a711
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 50 deletions.
1 change: 1 addition & 0 deletions kernel/api/sys/limits.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
#define OPEN_MAX 1024
#define SYMLINK_MAX 255
#define SYMLOOP_MAX 8
#define PIPE_BUF 4096
2 changes: 1 addition & 1 deletion kernel/console/serial_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ static serial_console_device* serial_console_device_create(uint16_t port) {
*dev = (serial_console_device){0};

dev->port = port;
int rc = ring_buf_init(&dev->input_buf);
int rc = ring_buf_init(&dev->input_buf, PAGE_SIZE);
if (IS_ERR(rc)) {
kfree(dev);
return ERR_PTR(rc);
Expand Down
2 changes: 1 addition & 1 deletion kernel/console/virtual_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ void virtual_console_init(struct screen* s) {
vt = vt_create(screen);
ASSERT(vt);

ASSERT_OK(ring_buf_init(&input_buf));
ASSERT_OK(ring_buf_init(&input_buf, PAGE_SIZE));
ps2_set_key_event_handler(on_key_event);

ASSERT_OK(vfs_register_device("tty", virtual_console_device_get()));
Expand Down
18 changes: 10 additions & 8 deletions kernel/fs/fifo.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "fs.h"
#include <kernel/api/fcntl.h>
#include <kernel/api/signum.h>
#include <kernel/api/sys/limits.h>
#include <kernel/api/sys/poll.h>
#include <kernel/panic.h>
#include <kernel/process.h>
Expand All @@ -9,6 +10,7 @@
struct fifo {
struct inode inode;
ring_buf buf;
mutex lock;
atomic_size_t num_readers;
atomic_size_t num_writers;
};
Expand Down Expand Up @@ -72,15 +74,15 @@ static ssize_t fifo_read(file_description* desc, void* buffer, size_t count) {
if (IS_ERR(rc))
return rc;

mutex_lock(&buf->lock);
mutex_lock(&fifo->lock);
if (!ring_buf_is_empty(buf)) {
ssize_t nread = ring_buf_read(buf, buffer, count);
mutex_unlock(&buf->lock);
mutex_unlock(&fifo->lock);
return nread;
}

bool no_writer = fifo->num_writers == 0;
mutex_unlock(&buf->lock);
mutex_unlock(&fifo->lock);
if (no_writer)
return 0;
}
Expand All @@ -101,22 +103,22 @@ static ssize_t fifo_write(file_description* desc, const void* buffer,
if (IS_ERR(rc))
return rc;

mutex_lock(&buf->lock);
mutex_lock(&fifo->lock);
if (fifo->num_readers == 0) {
mutex_unlock(&buf->lock);
mutex_unlock(&fifo->lock);
int rc = process_send_signal_to_one(current->pid, SIGPIPE);
if (IS_ERR(rc))
return rc;
return -EPIPE;
}

if (ring_buf_is_full(buf)) {
mutex_unlock(&buf->lock);
mutex_unlock(&fifo->lock);
continue;
}

ssize_t nwritten = ring_buf_write(buf, buffer, count);
mutex_unlock(&buf->lock);
mutex_unlock(&fifo->lock);
return nwritten;
}
}
Expand All @@ -141,7 +143,7 @@ struct inode* fifo_create(void) {
return ERR_PTR(-ENOMEM);
*fifo = (struct fifo){0};

int rc = ring_buf_init(&fifo->buf);
int rc = ring_buf_init(&fifo->buf, PIPE_BUF);
if (IS_ERR(rc)) {
kfree(fifo);
return ERR_PTR(rc);
Expand Down
53 changes: 27 additions & 26 deletions kernel/ring_buf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,62 @@
#include "api/errno.h"
#include "memory/memory.h"

#define BUF_CAPACITY 1024

int ring_buf_init(ring_buf* buf) {
*buf = (ring_buf){0};
buf->inner_buf = kmalloc(BUF_CAPACITY);
if (!buf->inner_buf)
int ring_buf_init(ring_buf* b, size_t capacity) {
*b = (ring_buf){0};
b->capacity = capacity;
b->write_index = b->read_index = 0;
b->ring = kmalloc(capacity);
if (!b->ring)
return -ENOMEM;
buf->write_idx = buf->read_idx = 0;
return 0;
}

void ring_buf_destroy(ring_buf* buf) { kfree(buf->inner_buf); }
void ring_buf_destroy(ring_buf* b) { kfree(b->ring); }

bool ring_buf_is_empty(const ring_buf* buf) {
return buf->write_idx == buf->read_idx;
bool ring_buf_is_empty(const ring_buf* b) {
return b->write_index == b->read_index;
}

bool ring_buf_is_full(const ring_buf* buf) {
return (buf->write_idx + 1) % BUF_CAPACITY == buf->read_idx;
bool ring_buf_is_full(const ring_buf* b) {
return (b->write_index + 1) % b->capacity == b->read_index;
}

ssize_t ring_buf_read(ring_buf* buf, void* bytes, size_t count) {
ssize_t ring_buf_read(ring_buf* b, void* bytes, size_t count) {
size_t nread = 0;
unsigned char* dest = bytes;
const unsigned char* src = buf->inner_buf;
const unsigned char* src = b->ring;
while (nread < count) {
dest[nread++] = src[buf->read_idx];
buf->read_idx = (buf->read_idx + 1) % BUF_CAPACITY;
if (buf->read_idx == buf->write_idx)
dest[nread++] = src[b->read_index];
b->read_index = (b->read_index + 1) % b->capacity;
if (b->read_index == b->write_index)
break;
}
return nread;
}

ssize_t ring_buf_write(ring_buf* buf, const void* bytes, size_t count) {
ssize_t ring_buf_write(ring_buf* b, const void* bytes, size_t count) {
size_t nwritten = 0;
unsigned char* dest = buf->inner_buf;
unsigned char* dest = b->ring;
const unsigned char* src = bytes;
while (nwritten < count) {
dest[buf->write_idx] = src[nwritten++];
buf->write_idx = (buf->write_idx + 1) % BUF_CAPACITY;
if ((buf->write_idx + 1) % BUF_CAPACITY == buf->read_idx)
dest[b->write_index] = src[nwritten++];
b->write_index = (b->write_index + 1) % b->capacity;
if ((b->write_index + 1) % b->capacity == b->read_index)
break;
}
return nwritten;
}

ssize_t ring_buf_write_evicting_oldest(ring_buf* buf, const void* bytes,
ssize_t ring_buf_write_evicting_oldest(ring_buf* b, const void* bytes,
size_t count) {
size_t nwritten = 0;
unsigned char* dest = buf->inner_buf;
unsigned char* dest = b->ring;
const unsigned char* src = bytes;
while (nwritten < count) {
dest[buf->write_idx] = src[nwritten++];
buf->write_idx = (buf->write_idx + 1) % BUF_CAPACITY;
dest[b->write_index] = src[nwritten++];
b->write_index = (b->write_index + 1) % b->capacity;
if (b->write_index == b->read_index)
b->read_index = (b->read_index + 1) % b->capacity;
}
return nwritten;
}
12 changes: 6 additions & 6 deletions kernel/ring_buf.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#include "api/sys/types.h"
#include "lock.h"
#include <common/extra.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h>

typedef struct ring_buf {
mutex lock;
void* inner_buf;
atomic_size_t write_idx;
atomic_size_t read_idx;
size_t capacity;
atomic_size_t write_index;
atomic_size_t read_index;
unsigned char* ring;
} ring_buf;

NODISCARD int ring_buf_init(ring_buf*);
NODISCARD int ring_buf_init(ring_buf*, size_t capacity);
void ring_buf_destroy(ring_buf*);
bool ring_buf_is_empty(const ring_buf*);
bool ring_buf_is_full(const ring_buf*);
Expand Down
16 changes: 8 additions & 8 deletions kernel/unix_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ static ssize_t unix_socket_read(file_description* desc, void* buffer,
if (IS_ERR(rc))
return rc;

mutex_lock(&buf->lock);
mutex_lock(&socket->lock);
if (!ring_buf_is_empty(buf)) {
ssize_t nread = ring_buf_read(buf, buffer, count);
mutex_unlock(&buf->lock);
mutex_unlock(&socket->lock);
return nread;
}
mutex_unlock(&buf->lock);
mutex_unlock(&socket->lock);

if (!is_open_for_reading(desc))
return 0;
Expand Down Expand Up @@ -106,13 +106,13 @@ static ssize_t unix_socket_write(file_description* desc, const void* buffer,
return -EPIPE;
}

mutex_lock(&buf->lock);
mutex_lock(&socket->lock);
if (!ring_buf_is_full(buf)) {
ssize_t nwritten = ring_buf_write(buf, buffer, count);
mutex_unlock(&buf->lock);
mutex_unlock(&socket->lock);
return nwritten;
}
mutex_unlock(&buf->lock);
mutex_unlock(&socket->lock);
}
}

Expand Down Expand Up @@ -156,12 +156,12 @@ unix_socket* unix_socket_create(void) {
socket->is_open_for_writing_to_connector = true;
socket->is_open_for_writing_to_acceptor = true;

int rc = ring_buf_init(&socket->to_acceptor_buf);
int rc = ring_buf_init(&socket->to_acceptor_buf, PAGE_SIZE);
if (IS_ERR(rc)) {
kfree(socket);
return ERR_PTR(rc);
}
rc = ring_buf_init(&socket->to_connector_buf);
rc = ring_buf_init(&socket->to_connector_buf, PAGE_SIZE);
if (IS_ERR(rc)) {
ring_buf_destroy(&socket->to_acceptor_buf);
kfree(socket);
Expand Down

0 comments on commit b50a711

Please sign in to comment.