| /* Copyright (c) 2015 Google Inc |
| * Davide Libenzi <dlibenzi@google.com> |
| * See LICENSE for details. |
| * |
| * The circular buffer interface allows to allocate once, and store atomic |
| * data blocks into it, with automatic drop of older blocks, when the buffer |
| * becomes full. |
| * Blocks are written atomically in the sense that when data is dropped from |
| * the head of the buffer, full blocks are dropped, so the circular buffer |
| * never returns partial blocks. |
| * Appending is O(1) WRT the number of blocks, while seeks are O(N). |
| * Reading data from the circular buffer interface, does not drop the read |
| * data from the head of the buffer (the head is pushed forward only when the |
| * write pointer wraps around and need more space for a new incoming write |
| * operation). |
| * The buffer can either be initialized with caller memory (if the "mem" |
| * parameter of circular_buffer_init() is not NULL), or it can allocate |
| * memory by itself in circular_buffer_init(). |
| * Once the initial (eventual) allocation is done, no more allocations will |
| * be performed. |
| */ |
| |
| #pragma once |
| |
| #include <sys/types.h> |
| #include <stdio.h> |
| |
| typedef uint32_t cbuf_size_t; |
| |
| struct circular_buffer { |
| char *mem; |
| char *base; |
| char *rdptr; |
| char *wrptr; |
| size_t size; |
| size_t allocated; |
| }; |
| |
| bool circular_buffer_init(struct circular_buffer *cb, size_t size, char *mem); |
| void circular_buffer_destroy(struct circular_buffer *cb); |
| void circular_buffer_clear(struct circular_buffer *cb); |
| size_t circular_buffer_write(struct circular_buffer *cb, const char *data, |
| size_t size); |
| size_t circular_buffer_read(struct circular_buffer *cb, char *data, size_t size, |
| size_t off); |
| |
| static inline size_t circular_buffer_size(const struct circular_buffer *cb) |
| { |
| return cb->size; |
| } |
| |
| static inline size_t circular_buffer_max_write_size( |
| const struct circular_buffer *cb) |
| { |
| return cb->allocated - 2 * sizeof(cbuf_size_t); |
| } |