1#pragma once
 2
 3#include <stdint.h>
 4
 5#include <threads.h>
 6#include <libpussy/sync.h>
 7
 8#ifdef __cplusplus
 9extern "C" {
10#endif
11
12/****************************************************************
13 * Basic ring buffer
14 */
15
16typedef struct {
17    uint8_t *data;
18    unsigned size;
19    unsigned head;
20    unsigned tail;
21} RingBuffer;
22
23bool init_ringbuffer(RingBuffer* ringbuf, unsigned size);
24/*
25 * Initialize ring buffer.
26 *
27 * `size` should be multiple of page size, although it is not
28 * strictly required. It will be rounded as necessary.
29 */
30
31void fini_ringbuffer(RingBuffer* ringbuf);
32/*
33 * Finalize ring buffer.
34 */
35
36RingBuffer* create_ringbuffer(unsigned size);
37/*
38 * Allocate RingBuffer structure and call init_ringbuffer.
39 */
40
41void delete_ringbuffer(RingBuffer** ringbuf_ptr);
42/*
43 * Destructor.
44 * The type of argument is natural for autocleaned variables.
45 */
46
47bool grow_ringbuffer(RingBuffer* ringbuf, unsigned new_size);
48/*
49 * Reallocate buffer to new size.
50 */
51
52void shrink_ringbuffer(RingBuffer* ringbuf, unsigned new_size);
53/*
54 * Release unused pages back to the system,
55 * making the buffer as small as possible but no smaller than `new_size`.
56 */
57
58unsigned read_ringbuffer(RingBuffer* ringbuf, uint8_t* buffer, unsigned size);
59/*
60 * Read the data from ring buffer.
61 * Return the number of bytes read.
62 */
63
64bool write_ringbuffer(RingBuffer* ringbuf, uint8_t* data, unsigned size);
65/*
66 * Write the data into ring buffer.
67 *
68 * Return false if no memory available in the buffer.
69 */
70
71/****************************************************************
72 * Ring buffer with synchronization
73 */
74
75typedef struct {
76    RingBuffer  ringbuf;
77    mtx_t       lock;  // mutex to serialize ring buffer operations
78    Event*      more;  // set when data is written to buffer
79    Event*      less;  // set when data is read from buffer or the buffer is extended
80} SyncRingBuffer;
81
82bool srb_init(SyncRingBuffer* ringbuf, unsigned size);
83void srb_fini(SyncRingBuffer* ringbuf);
84SyncRingBuffer* srb_create(unsigned size);
85void srb_delete(SyncRingBuffer** srb_ptr);
86bool srb_grow(SyncRingBuffer* srb, unsigned new_size);
87void srb_shrink(SyncRingBuffer* srb, unsigned new_size);
88unsigned srb_read(SyncRingBuffer* srb, uint8_t* buffer, unsigned size);
89bool srb_write(SyncRingBuffer* srb, uint8_t* data, unsigned size);
90
91#ifdef __cplusplus
92}
93#endif