Make the syscall error detector a kernel header (XCC)
[akaros.git] / kern / include / circular_buffer.h
1 /* Copyright (c) 2015 Google Inc
2  * Davide Libenzi <dlibenzi@google.com>
3  * See LICENSE for details.
4  *
5  * The circular buffer interface allows to allocate once, and store atomic
6  * data blocks into it, with automatic drop of older blocks, when the buffer
7  * becomes full.
8  * Blocks are written atomically in the sense that when data is dropped from
9  * the head of the buffer, full blocks are dropped, so the circular buffer
10  * never returns partial blocks.
11  * Appending is O(1) WRT the number of blocks, while seeks are O(N).
12  * Reading data from the circular buffer interface, does not drop  the read
13  * data from the head of the buffer (the head is pushed forward only when the
14  * write pointer wraps around and need more space for a new incoming write
15  * operation).
16  * The buffer can either be initialized with caller memory (if the "mem"
17  * parameter of circular_buffer_init() is not NULL), or it can allocate
18  * memory by itself in circular_buffer_init().
19  * Once the initial (eventual) allocation is done, no more allocations will
20  * be performed.
21  */
22
23 #pragma once
24
25 #include <sys/types.h>
26 #include <stdio.h>
27
28 typedef uint32_t cbuf_size_t;
29
30 struct circular_buffer {
31         char *mem;
32         char *base;
33         char *rdptr;
34         char *wrptr;
35         size_t size;
36         size_t allocated;
37 };
38
39 bool circular_buffer_init(struct circular_buffer *cb, size_t size, char *mem);
40 void circular_buffer_destroy(struct circular_buffer *cb);
41 void circular_buffer_clear(struct circular_buffer *cb);
42 size_t circular_buffer_write(struct circular_buffer *cb, const char *data,
43                                                          size_t size);
44 size_t circular_buffer_read(struct circular_buffer *cb, char *data, size_t size,
45                                                         size_t off);
46
47 static inline size_t circular_buffer_size(const struct circular_buffer *cb)
48 {
49         return cb->size;
50 }
51
52 static inline size_t circular_buffer_max_write_size(
53         const struct circular_buffer *cb)
54 {
55         return cb->allocated - 2 * sizeof(cbuf_size_t);
56 }