From df9cd367a30b46a7a7e59159addabdf1b6aeb51b Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Tue, 2 Jul 2024 05:39:08 +0200 Subject: [PATCH 1/2] .so and .a target --- .gitignore | 2 ++ Makefile | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 46ca31e..32aec77 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ *.o *.s +*.so +*.a build driver diff --git a/Makefile b/Makefile index e1cb59a..49f09d0 100644 --- a/Makefile +++ b/Makefile @@ -39,8 +39,18 @@ driver: $(OBJECTS) run: driver @./driver +lib: $(OBJECTS) + @ar rcs librbuf.a ringbuf.o + +dylib: $(OBJECTS) + @$(CC) $(CFLAGS) -fPIC -shared -o librbuf.so ringbuf.o + +install: + @cp librbuf.a /usr/local/lib + @cp ringbuf.h /usr/local/include + clean: - rm -f $(OBJECTS) $(ASMS) driver + rm -f $(OBJECTS) $(ASMS) driver librbuf.a librbuf.so asm: $(ASMS) $(OBJECTS) wc -l $(ASMS) From c4f1ede6b01c5a66d211e94ed295a4e34c05373b Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Tue, 2 Jul 2024 05:39:21 +0200 Subject: [PATCH 2/2] rb_push_many first draft --- ringbuf.c | 41 +++++++++++++++++++++++++++++++++++++++++ ringbuf.h | 22 ++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/ringbuf.c b/ringbuf.c index 5c004ba..d0b4621 100644 --- a/ringbuf.c +++ b/ringbuf.c @@ -63,6 +63,47 @@ rb_push_back(struct RingBuf *rb, const void *item, MEMCPY_T memcpy_fn) return WriteOk; } +enum WriteResult +rb_push_many(struct RingBuf *rb, const void *items, MEMCPY_T memcpy_fn, + rb_size_t n) +{ + if(rb->count + n > rb->capacity) + return Full; // Perhaps rename to InsufficientSpace + + // If the write head will move past the end of the buffer + // we need to to the write in two steps. + void *end = (char *)rb->write_head + rb->struct_size * n; + + if(end > rb->buffer_end) { + + // Calculate the number of items that can be written in the first chunk + rb_size_t first_chunk = (char *)rb->buffer_end - (char *)rb->write_head; + + DEBUG_PRINT("Multi-chunk write. First chunk: %d\n", first_chunk); + + // Write the first chunk + memcpy_fn(rb->write_head, items, rb->struct_size * first_chunk); + + // Set the write head to the beginning of the buffer + rb->write_head = rb->buffer; + rb->count += first_chunk; + n -= first_chunk; + } else { + DEBUG_PRINT("Single-chunk write. No need to wrap around.%s\n", ""); + } + + DEBUG_PRINT("Writing %d items\n", n); + memcpy_fn(rb->write_head, items, rb->struct_size * n); + if(rb->write_head == rb->buffer_end) + rb->write_head = rb->buffer; + + // Advance the write head + rb->write_head = (char *)rb->write_head + rb->struct_size * n; + rb->count+=n; + + return WriteOk; +} + enum ReadResult rb_pop_front(struct RingBuf *rb, void *item) { diff --git a/ringbuf.h b/ringbuf.h index a017a7f..f374bac 100644 --- a/ringbuf.h +++ b/ringbuf.h @@ -49,6 +49,28 @@ void rb_init(struct RingBuf *rb, rb_size_t capacity, ALLOC_T alloc, enum WriteResult rb_push_back(struct RingBuf *rb, const void *item, MEMCPY_T memcpy_fn); +/** + * @brief Insert multiple data to the ring buffer + * + * @details This function is more efficient than calling rb_push_back multiple + * times. It only advances the write head once, and attempts to write all the + * memory in one go. + * + * If n is greater than the capacity, it will return Full. + * If the full write will overflow, it will wrap around. + * + * If the buffer is full, it will return Full and not write + * anything. + * + * @param rb The ring buffer + * @param items The items to insert + * @param memcpy_fn The memcpy function + * @param n The number of items to insert + * @return WriteResult + */ +enum WriteResult rb_push_many(struct RingBuf *rb, const void *items, + MEMCPY_T memcpy_fn, rb_size_t n); + /** * @brief Read data from the ring buffer * @param rb The ring buffer