diff --git a/kernel/inc/utils/stream.h b/kernel/inc/utils/stream.h new file mode 100644 index 0000000..748ed5f --- /dev/null +++ b/kernel/inc/utils/stream.h @@ -0,0 +1,20 @@ +// This file is part of noxos and licensed under the MIT open source license + +#ifndef NOX_STREAM_H +#define NOX_STREAM_H + +#include "utils/stdtypes.h" + +typedef struct { + uint8_t* buffer; + uint32_t size; + uint32_t pos_sender; + uint32_t pos_receiver; +} stream_T; + +stream_T* stream_alloc (uint32_t size); +void stream_destruct (stream_T* stream); +uint32_t stream_write (stream_T* stream, void* buffer_in, uint32_t n); +uint32_t stream_read (stream_T* stream, void* buffer_out, uint32_t n); + +#endif //NOX_STREAM_H diff --git a/kernel/src/utils/stream.c b/kernel/src/utils/stream.c new file mode 100644 index 0000000..9ab297c --- /dev/null +++ b/kernel/src/utils/stream.c @@ -0,0 +1,64 @@ +// This file is part of noxos and licensed under the MIT open source license + +#include "utils/stream.h" +#include "utils/memory.h" +#include "utils/math.h" + +stream_T* stream_alloc(uint32_t size) { + stream_T* stream = memory_allocate(sizeof(stream_T)); + + stream->buffer = memory_allocate(size); + stream->size = size; + stream->pos_sender = 0; + stream->pos_receiver = 0; + + return stream; +} + +void stream_destruct(stream_T* stream) { + memory_free(stream->buffer); + memory_free(stream); +} + +#include "utils/logger.h" + +uint32_t stream_write(stream_T* stream, void* buffer_in, uint32_t n) { + uint32_t num_top; + uint32_t num_bottom; + if (stream->pos_receiver > stream->pos_sender) { + num_top = MIN(n, stream->pos_receiver - stream->pos_sender - 1); + num_bottom = 0; + } else { + num_top = MIN(n, stream->size - stream->pos_sender); + num_bottom = MIN(n - num_top, stream->pos_receiver - 1); + } + + memory_copy(buffer_in, &stream->buffer[stream->pos_sender], num_top); + memory_copy(&buffer_in[num_top], stream->buffer, num_bottom); + + stream->pos_sender += num_top + num_bottom; + stream->pos_sender %= stream->size; + + return num_top + num_bottom; +} + +uint32_t stream_read(stream_T* stream, void* buffer_out, uint32_t n) { + uint32_t num_top; + uint32_t num_bottom; + + if (stream->pos_sender > stream->pos_receiver) { + num_top = MIN(n, stream->pos_sender - stream->pos_receiver - 1); + num_bottom = 0; + } else { + num_top = MIN(n, stream->size - stream->pos_receiver); + num_bottom = MIN(n - num_top, stream->pos_sender - 1); + } + + memory_copy(&stream->buffer[stream->pos_receiver], buffer_out, num_top); + memory_copy(stream->buffer, &buffer_out[num_top], num_bottom); + + stream->pos_receiver += num_top + num_bottom; + stream->pos_receiver %= stream->size; + + return num_top + num_bottom; +} \ No newline at end of file